From b51d5b5f06948960f0bfd4ad974e625ca2350936 Mon Sep 17 00:00:00 2001
From: Apple <opensource@apple.com>
Date: Thu, 4 Jul 2002 04:54:59 +0000
Subject: [PATCH] system_cmds-230.tar.gz

---
 Makefile                                      |   15 +-
 PB.project                                    |  129 +-
 README.rtf                                    |   23 +-
 ac.tproj/Makefile.postamble                   |    4 +
 ac.tproj/Makefile.preamble                    |    1 +
 arch.tproj/Makefile                           |    2 +-
 arch.tproj/Makefile.postamble                 |    5 +-
 arch.tproj/arch.1                             |   46 +
 .../kmodstat.8 => arch.tproj/machine.1        |   59 +-
 at.tproj/Makefile.postamble                   |    7 +
 fs_usage.tproj/Makefile                       |    2 +-
 fs_usage.tproj/fs_usage.1                     |   20 +-
 fs_usage.tproj/fs_usage.c                     |  800 ++++++-
 init.tproj/Makefile.postamble                 |    5 +-
 init.tproj/Makefile.preamble                  |    2 +-
 init.tproj/init.c                             |    2 +-
 iostat.tproj/Makefile                         |    4 +-
 iostat.tproj/Makefile.postamble               |    4 +-
 iostat.tproj/PB.project                       |    3 +-
 iostat.tproj/iostat.8                         |  226 +-
 iostat.tproj/iostat.c                         | 1057 +++++---
 iostat.tproj/names.c                          |  268 ---
 {kextload.tproj => kdump.tproj}/Makefile      |   18 +-
 kdump.tproj/Makefile.postamble                |    8 +
 kdump.tproj/Makefile.preamble                 |    7 +
 kdump.tproj/PB.project                        |   42 +
 kdump.tproj/kdump.1                           |  102 +
 kdump.tproj/kdump.c                           |  490 ++++
 kdump.tproj/mkioctls                          |   91 +
 kdump.tproj/syscalls.c                        |  375 +++
 kextd.tproj/GetSymbolFromPEF.h                |  204 --
 kextd.tproj/KEXTD.c                           | 1838 --------------
 kextd.tproj/KEXTD.h                           |   65 -
 kextd.tproj/KEXTD_main.c                      |  138 --
 kextd.tproj/Makefile                          |   53 -
 kextd.tproj/Makefile.preamble                 |  137 --
 kextd.tproj/PB.project                        |   29 -
 kextd.tproj/PEFSupport.c                      |  711 ------
 kextd.tproj/PTLock.c                          |   95 -
 kextd.tproj/PTLock.h                          |   25 -
 kextload.tproj/Makefile.postamble             |    9 -
 kextload.tproj/Makefile.preamble              |  137 --
 kextload.tproj/PB.project                     |   26 -
 kextload.tproj/kextload.8                     |   73 -
 kextload.tproj/kextload_main.c                |  629 -----
 kextunload.tproj/Makefile                     |   49 -
 kextunload.tproj/Makefile.postamble           |    9 -
 kextunload.tproj/Makefile.preamble            |  137 --
 kextunload.tproj/PB.project                   |   25 -
 kextunload.tproj/kextunload.8                 |   43 -
 kextunload.tproj/kextunload_main.c            |  278 ---
 kmodload.tproj/Makefile                       |   51 -
 kmodload.tproj/Makefile.postamble             |  110 -
 kmodload.tproj/Makefile.preamble              |  137 --
 kmodload.tproj/PB.project                     |   28 -
 kmodload.tproj/kld_patch.c                    | 2124 -----------------
 kmodload.tproj/kld_patch.h                    |   56 -
 kmodload.tproj/kmodload.8                     |   93 -
 kmodload.tproj/kmodload.c                     |  730 ------
 kmodload.tproj/kmodsyms.8                     |  105 -
 kmodstat.tproj/Makefile                       |   48 -
 kmodstat.tproj/Makefile.preamble              |  137 --
 kmodstat.tproj/PB.project                     |   25 -
 kmodstat.tproj/kmodstat.c                     |  203 --
 kmodunload.tproj/Makefile                     |   48 -
 kmodunload.tproj/Makefile.postamble           |  106 -
 kmodunload.tproj/Makefile.preamble            |  137 --
 kmodunload.tproj/PB.project                   |   25 -
 kmodunload.tproj/kmodunload.8                 |   69 -
 kmodunload.tproj/kmodunload.c                 |  209 --
 ktrace.tproj/Makefile                         |    2 +-
 ktrace.tproj/Makefile.postamble               |    4 +
 ktrace.tproj/Makefile.preamble                |    1 +
 ktrace.tproj/PB.project                       |    2 +-
 ktrace.tproj/ktrace.1                         |   41 +-
 ktrace.tproj/ktrace.c                         |   58 +-
 ktrace.tproj/ktrace.h                         |   25 +-
 ktrace.tproj/subr.c                           |   19 +-
 latency.tproj/Makefile                        |    2 +-
 latency.tproj/latency.c                       |  222 +-
 login.tproj/Makefile                          |    2 +-
 login.tproj/Makefile.postamble                |    6 +-
 login.tproj/Makefile.preamble                 |    2 +
 login.tproj/login.c                           |  165 +-
 mach_init.tproj/Makefile                      |   10 +-
 .../Makefile.postamble                        |   10 +-
 mach_init.tproj/Makefile.preamble             |    2 +-
 mach_init.tproj/Notes                         |   71 -
 mach_init.tproj/PB.project                    |   63 +-
 mach_init.tproj/bootstrap.c                   | 1501 +++++++-----
 mach_init.tproj/bootstrap.defs                |  228 +-
 mach_init.tproj/bootstrap_internal.h          |   17 +-
 mach_init.tproj/error_log.c                   |   55 +-
 mach_init.tproj/error_log.h                   |    5 +-
 mach_init.tproj/initConf                      |    7 -
 mach_init.tproj/lists.c                       |  309 ++-
 mach_init.tproj/lists.h                       |   58 +-
 mach_init.tproj/mach_init.8                   |  100 +
 mach_init.tproj/parser.c                      |  495 ----
 mach_init.tproj/parser.h                      |   35 -
 mach_init.tproj/rpc_services.c                |  436 +++-
 mach_init.tproj/testConfig                    |    7 -
 mach_init.tproj/testConfig2                   |    1 -
 mach_init.tproj/testServer/Makefile           |   19 -
 mach_init.tproj/testServer/boot_subset.c      |  157 --
 mach_init.tproj/testServer/listServer.c       |   93 -
 mach_init.tproj/testServer/testServer.c       |  436 ----
 mkfile.tproj/Makefile                         |    2 +-
 mkfile.tproj/Makefile.postamble               |    3 +
 mkfile.tproj/mkfile.8                         |   47 +
 nologin.tproj/Makefile.postamble              |    7 +
 nologin.tproj/nologin.8                       |   13 +-
 nvram.tproj/nvram.8                           |    8 +-
 nvram.tproj/nvram.c                           |    7 +-
 sc_usage.tproj/Makefile                       |    2 +-
 sc_usage.tproj/sc_usage.c                     |   74 +-
 sc_usage.tproj/trace.codes                    |  262 +-
 sysctl.tproj/Makefile.postamble               |    4 +
 sysctl.tproj/Makefile.preamble                |    1 +
 sysctl.tproj/sysctl.8                         |    2 +-
 sysctl.tproj/sysctl.c                         |   45 +-
 top.tproj/Makefile                            |    2 +-
 top.tproj/top.c                               |   82 +-
 update.tproj/Makefile.postamble               |    4 +
 update.tproj/Makefile.preamble                |    1 +
 vm_stat.tproj/Makefile                        |    2 +-
 vm_stat.tproj/Makefile.postamble              |    3 +
 vm_stat.tproj/vm_stat.1                       |   60 +
 zic.tproj/HACK/CST6CDT                        |  Bin 1262 -> 1279 bytes
 zic.tproj/HACK/Cuba                           |  Bin 883 -> 891 bytes
 zic.tproj/HACK/EST                            |  Bin 269 -> 286 bytes
 zic.tproj/HACK/EST5EDT                        |  Bin 1250 -> 1267 bytes
 zic.tproj/HACK/Egypt                          |  Bin 939 -> 955 bytes
 zic.tproj/HACK/Eire                           |  Bin 1285 -> 1285 bytes
 zic.tproj/HACK/Factory                        |  Bin 101 -> 93 bytes
 zic.tproj/HACK/HST                            |  Bin 113 -> 130 bytes
 zic.tproj/HACK/Hongkong                       |  Bin 443 -> 426 bytes
 zic.tproj/HACK/Israel                         |  Bin 413 -> 803 bytes
 zic.tproj/HACK/Jamaica                        |  Bin 185 -> 185 bytes
 zic.tproj/HACK/Japan                          |  Bin 56 -> 73 bytes
 zic.tproj/HACK/Libya                          |  Bin 669 -> 238 bytes
 zic.tproj/HACK/MST                            |  Bin 130 -> 130 bytes
 zic.tproj/HACK/MST7MDT                        |  Bin 860 -> 877 bytes
 zic.tproj/HACK/Navajo                         |  Bin 860 -> 877 bytes
 zic.tproj/HACK/PST8PDT                        |  Bin 1000 -> 1017 bytes
 zic.tproj/HACK/Poland                         |  Bin 940 -> 961 bytes
 zic.tproj/HACK/Portugal                       |  Bin 1265 -> 1264 bytes
 zic.tproj/HACK/W-SU                           |  Bin 802 -> 815 bytes
 zic.tproj/Makefile.postamble                  |    8 +-
 zic.tproj/datfiles/africa                     |  410 ++--
 zic.tproj/datfiles/antarctica                 |  218 +-
 zic.tproj/datfiles/asia                       |  681 ++++--
 zic.tproj/datfiles/australasia                |  648 +++--
 zic.tproj/datfiles/backward                   |   12 +-
 zic.tproj/datfiles/etcetera                   |   31 +-
 zic.tproj/datfiles/europe                     | 1513 +++++-------
 zic.tproj/datfiles/factory                    |    5 +-
 zic.tproj/datfiles/leapseconds                |   31 +-
 zic.tproj/datfiles/northamerica               |  791 ++++--
 zic.tproj/datfiles/southamerica               |  558 +++--
 zic.tproj/datfiles/systemv                    |   66 +-
 161 files changed, 8656 insertions(+), 14581 deletions(-)
 create mode 100644 arch.tproj/arch.1
 rename kmodstat.tproj/kmodstat.8 => arch.tproj/machine.1 (56%)
 delete mode 100644 iostat.tproj/names.c
 rename {kextload.tproj => kdump.tproj}/Makefile (70%)
 create mode 100644 kdump.tproj/Makefile.postamble
 create mode 100644 kdump.tproj/Makefile.preamble
 create mode 100644 kdump.tproj/PB.project
 create mode 100644 kdump.tproj/kdump.1
 create mode 100644 kdump.tproj/kdump.c
 create mode 100644 kdump.tproj/mkioctls
 create mode 100644 kdump.tproj/syscalls.c
 delete mode 100644 kextd.tproj/GetSymbolFromPEF.h
 delete mode 100644 kextd.tproj/KEXTD.c
 delete mode 100644 kextd.tproj/KEXTD.h
 delete mode 100644 kextd.tproj/KEXTD_main.c
 delete mode 100644 kextd.tproj/Makefile
 delete mode 100644 kextd.tproj/Makefile.preamble
 delete mode 100644 kextd.tproj/PB.project
 delete mode 100644 kextd.tproj/PEFSupport.c
 delete mode 100644 kextd.tproj/PTLock.c
 delete mode 100644 kextd.tproj/PTLock.h
 delete mode 100644 kextload.tproj/Makefile.postamble
 delete mode 100644 kextload.tproj/Makefile.preamble
 delete mode 100644 kextload.tproj/PB.project
 delete mode 100644 kextload.tproj/kextload.8
 delete mode 100644 kextload.tproj/kextload_main.c
 delete mode 100644 kextunload.tproj/Makefile
 delete mode 100644 kextunload.tproj/Makefile.postamble
 delete mode 100644 kextunload.tproj/Makefile.preamble
 delete mode 100644 kextunload.tproj/PB.project
 delete mode 100644 kextunload.tproj/kextunload.8
 delete mode 100644 kextunload.tproj/kextunload_main.c
 delete mode 100644 kmodload.tproj/Makefile
 delete mode 100644 kmodload.tproj/Makefile.postamble
 delete mode 100644 kmodload.tproj/Makefile.preamble
 delete mode 100644 kmodload.tproj/PB.project
 delete mode 100644 kmodload.tproj/kld_patch.c
 delete mode 100644 kmodload.tproj/kld_patch.h
 delete mode 100644 kmodload.tproj/kmodload.8
 delete mode 100644 kmodload.tproj/kmodload.c
 delete mode 100644 kmodload.tproj/kmodsyms.8
 delete mode 100644 kmodstat.tproj/Makefile
 delete mode 100644 kmodstat.tproj/Makefile.preamble
 delete mode 100644 kmodstat.tproj/PB.project
 delete mode 100644 kmodstat.tproj/kmodstat.c
 delete mode 100644 kmodunload.tproj/Makefile
 delete mode 100644 kmodunload.tproj/Makefile.postamble
 delete mode 100644 kmodunload.tproj/Makefile.preamble
 delete mode 100644 kmodunload.tproj/PB.project
 delete mode 100644 kmodunload.tproj/kmodunload.8
 delete mode 100644 kmodunload.tproj/kmodunload.c
 create mode 100644 ktrace.tproj/Makefile.postamble
 rename {kmodstat.tproj => mach_init.tproj}/Makefile.postamble (95%)
 delete mode 100644 mach_init.tproj/Notes
 delete mode 100644 mach_init.tproj/initConf
 create mode 100644 mach_init.tproj/mach_init.8
 delete mode 100644 mach_init.tproj/parser.c
 delete mode 100644 mach_init.tproj/parser.h
 delete mode 100644 mach_init.tproj/testConfig
 delete mode 100644 mach_init.tproj/testConfig2
 delete mode 100644 mach_init.tproj/testServer/Makefile
 delete mode 100644 mach_init.tproj/testServer/boot_subset.c
 delete mode 100644 mach_init.tproj/testServer/listServer.c
 delete mode 100644 mach_init.tproj/testServer/testServer.c
 create mode 100644 mkfile.tproj/Makefile.postamble
 create mode 100644 mkfile.tproj/mkfile.8
 create mode 100644 vm_stat.tproj/vm_stat.1

diff --git a/Makefile b/Makefile
index 6a01016..e567192 100644
--- a/Makefile
+++ b/Makefile
@@ -12,18 +12,15 @@ NAME = system_cmds
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Aggregate
 
-SUBPROJECTS = 
-
 TOOLS = dynamic_pager.tproj ac.tproj accton.tproj arch.tproj at.tproj\
         atrun.tproj chkpasswd.tproj chpass.tproj dmesg.tproj\
         getty.tproj halt.tproj hostinfo.tproj init.tproj iostat.tproj\
-        kgmon.tproj kmodload.tproj kmodstat.tproj kmodunload.tproj\
-        ktrace.tproj login.tproj mach_init.tproj makekey.tproj\
-        mkfile.tproj nvram.tproj passwd.tproj pwd_mkdb.tproj\
-        reboot.tproj shutdown.tproj sync.tproj sysctl.tproj\
-        update.tproj vipw.tproj zic.tproj zdump.tproj vm_stat.tproj\
-        zprint.tproj top.tproj kextload.tproj kextunload.tproj kextd.tproj\
-        latency.tproj sc_usage.tproj fs_usage.tproj
+        kgmon.tproj ktrace.tproj login.tproj mach_init.tproj\
+        makekey.tproj mkfile.tproj nvram.tproj passwd.tproj\
+        pwd_mkdb.tproj reboot.tproj shutdown.tproj sync.tproj\
+        sysctl.tproj update.tproj vipw.tproj zic.tproj zdump.tproj\
+        vm_stat.tproj zprint.tproj top.tproj latency.tproj\
+        sc_usage.tproj fs_usage.tproj kdump.tproj
 
 LIBRARIES = dp_notify_lib
 
diff --git a/PB.project b/PB.project
index 295cf6e..8f42f58 100644
--- a/PB.project
+++ b/PB.project
@@ -1,79 +1,74 @@
 {
-    English_RESOURCES = {}; 
+    "English_RESOURCES" = {}; 
     FILESTABLE = {
-        CLASSES = (zprint.c); 
-        C_FILES = (); 
+        CLASSES = ("zprint.c"); 
+        "C_FILES" = (); 
         FRAMEWORKS = (); 
         HEADERSEARCH = (); 
-        H_FILES = (); 
-        M_FILES = (); 
-        OTHER_LINKED = (); 
-        OTHER_SOURCES = (Makefile.preamble, Makefile, README.rtf, APPLE_LICENSE); 
-        PRECOMPILED_HEADERS = (); 
-        PROJECT_HEADERS = (); 
-        PUBLIC_HEADERS = (); 
+        "H_FILES" = (); 
+        "M_FILES" = (); 
+        "OTHER_LINKED" = (); 
+        "OTHER_SOURCES" = ("Makefile.preamble", Makefile, "README.rtf", "APPLE_LICENSE"); 
+        "PRECOMPILED_HEADERS" = (); 
+        "PROJECT_HEADERS" = (); 
+        "PUBLIC_HEADERS" = (); 
         SUBPROJECTS = (
-            dynamic_pager.tproj, 
-            dp_notify_lib, 
-            ac.tproj, 
-            accton.tproj, 
-            arch.tproj, 
-            at.tproj, 
-            atrun.tproj, 
-            chkpasswd.tproj, 
-            chpass.tproj, 
-            dmesg.tproj, 
-            fastboot.tproj, 
-            getty.tproj, 
-            halt.tproj, 
-            hostinfo.tproj, 
-            init.tproj, 
-            iostat.tproj, 
-            kgmon.tproj, 
-            kmodload.tproj, 
-            kmodstat.tproj, 
-            kmodunload.tproj, 
-            ktrace.tproj, 
-            login.tproj, 
-            mach_init.tproj, 
-            makekey.tproj, 
-            mkfile.tproj, 
-            nologin.tproj, 
-            nvram.tproj, 
-            pagesize.tproj, 
-            passwd.tproj, 
-            pwd_mkdb.tproj, 
-            reboot.tproj, 
-            shutdown.tproj, 
-            sync.tproj, 
-            sysctl.tproj, 
-            update.tproj, 
-            vipw.tproj, 
-            zic.tproj, 
-            zdump.tproj, 
-            vm_stat.tproj, 
-            zprint.tproj, 
-            top.tproj, 
-            kextload.tproj, 
-            kextunload.tproj, 
-            kextd.tproj, 
-            latency.tproj, 
-            sc_usage.tproj, 
-            fs_usage.tproj
+            "dynamic_pager.tproj", 
+            "dp_notify_lib", 
+            "ac.tproj", 
+            "accton.tproj", 
+            "arch.tproj", 
+            "at.tproj", 
+            "atrun.tproj", 
+            "chkpasswd.tproj", 
+            "chpass.tproj", 
+            "dmesg.tproj", 
+            "fastboot.tproj", 
+            "getty.tproj", 
+            "halt.tproj", 
+            "hostinfo.tproj", 
+            "init.tproj", 
+            "iostat.tproj", 
+            "kgmon.tproj", 
+            "ktrace.tproj", 
+            "login.tproj", 
+            "mach_init.tproj", 
+            "makekey.tproj", 
+            "mkfile.tproj", 
+            "nologin.tproj", 
+            "nvram.tproj", 
+            "pagesize.tproj", 
+            "passwd.tproj", 
+            "pwd_mkdb.tproj", 
+            "reboot.tproj", 
+            "shutdown.tproj", 
+            "sync.tproj", 
+            "sysctl.tproj", 
+            "update.tproj", 
+            "vipw.tproj", 
+            "zic.tproj", 
+            "zdump.tproj", 
+            "vm_stat.tproj", 
+            "zprint.tproj", 
+            "top.tproj", 
+            "latency.tproj", 
+            "sc_usage.tproj", 
+            "fs_usage.tproj", 
+            "kdump.tproj"
         ); 
     }; 
     LANGUAGE = English; 
-    LOCALIZABLE_FILES = {}; 
+    "LOCALIZABLE_FILES" = {}; 
     MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
-    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
-    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
-    PROJECTNAME = system_cmds; 
+    "NEXTSTEP_BUILDTOOL" = "/bin/gnumake"; 
+    "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac"; 
+    "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc"; 
+    "PDO_UNIX_JAVA_COMPILER" = "$(NEXTDEV_BIN)/javac"; 
+    "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = "system_cmds"; 
     PROJECTTYPE = Aggregate; 
-    PROJECTVERSION = 2.8; 
+    PROJECTVERSION = "2.8"; 
     TARGETS = (); 
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+    "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe"; 
+    "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc"; 
 }
diff --git a/README.rtf b/README.rtf
index a8eb014..9e6cc5b 100644
--- a/README.rtf
+++ b/README.rtf
@@ -1,11 +1,13 @@
-{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
-\paperw4880
-\paperh7420
-\margl120
-\margr120
-\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\ulnone\fs24\fc0\cf0 system_cmds failures\
+{\rtf1\mac\ansicpg10000\cocoartf100
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;\f2\fswiss\fcharset77 Helvetica-Oblique;
+}
+{\colortbl;\red255\green255\blue255;}
+\margl120\margr120\vieww4640\viewh7420\viewkind0
+\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\ql\qnatural
+
+\f0\b\fs24 \cf0 system_cmds failures\
 
-\b0 \
+\f1\b0 \
 cgore\
 	<a.out.h>\
 \
@@ -19,13 +21,12 @@ kvm_mkdb\
 	KERNBASE undeclared\
 \
 mach_swapon\
-	<bsd/sys/table.h> not found\
+	<sys/table.h> not found\
 	\
 savecore\
 	KERNBASE undeclared\
 \
 vmstat\
 
-\i 	<vm/vm.h> not found\
-
-}
+\f2\i 	<vm/vm.h> not found\
+}
\ No newline at end of file
diff --git a/ac.tproj/Makefile.postamble b/ac.tproj/Makefile.postamble
index 70b747f..a9b68c9 100644
--- a/ac.tproj/Makefile.postamble
+++ b/ac.tproj/Makefile.postamble
@@ -107,3 +107,7 @@
 # Makefile API), which are rules that get invoked before and after the install 
 # target runs.  Such rules should be specified with the '::' syntax rather than 
 # a single colon.
+
+after_install:
+	mkdir -p "$(DSTROOT)/usr/share/man/man8"
+	install -c -m 644 ac.8 "$(DSTROOT)/usr/share/man/man8/ac.8"
diff --git a/ac.tproj/Makefile.preamble b/ac.tproj/Makefile.preamble
index fc1c649..e5a7929 100644
--- a/ac.tproj/Makefile.preamble
+++ b/ac.tproj/Makefile.preamble
@@ -110,3 +110,4 @@ OTHER_HELP_DIRS =
 # $(NAME).%d[.%d][.%d] and the following line must be uncommented.
 OTHER_GENERATED_OFILES = $(VERS_OFILE)
 
+AFTER_INSTALL = after_install
diff --git a/arch.tproj/Makefile b/arch.tproj/Makefile
index 20bbb50..c490a16 100644
--- a/arch.tproj/Makefile
+++ b/arch.tproj/Makefile
@@ -14,7 +14,7 @@ PROJECT_TYPE = Tool
 
 CFILES = arch.c
 
-OTHERSRCS = Makefile PB.project Makefile.postamble
+OTHERSRCS = Makefile PB.project Makefile.postamble arch.1 machine.1
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
diff --git a/arch.tproj/Makefile.postamble b/arch.tproj/Makefile.postamble
index eaf5363..e031809 100644
--- a/arch.tproj/Makefile.postamble
+++ b/arch.tproj/Makefile.postamble
@@ -1,3 +1,6 @@
 after_install::
+	install -d $(DSTROOT)/usr/share/man/man1
+	install -c -m 444 arch.1 $(DSTROOT)/usr/share/man/man1
+	install -c -m 444 machine.1 $(DSTROOT)/usr/share/man/man1
 	@-$(RM) -f $(DSTROOT)$(INSTALLDIR)/machine
-	ln $(DSTROOT)$(INSTALLDIR)/arch $(DSTROOT)$(INSTALLDIR)/machine
\ No newline at end of file
+	ln $(DSTROOT)$(INSTALLDIR)/arch $(DSTROOT)$(INSTALLDIR)/machine
diff --git a/arch.tproj/arch.1 b/arch.tproj/arch.1
new file mode 100644
index 0000000..71ce882
--- /dev/null
+++ b/arch.tproj/arch.1
@@ -0,0 +1,46 @@
+.\" Copyright (c) 1994 SigmaSoft, Th. Lockert
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"      This product includes software developed by SigmaSoft, Th. Lockert.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\"	$OpenBSD: arch.1,v 1.2 1996/06/29 20:29:34 tholo Exp $
+.\"
+.\" Modifications made 8/20/97 (c) Apple Computer, Inc.
+
+.Dd August 20, 1997
+.Dt ARCH 1
+.Os Mac OS X
+.Sh NAME
+.Nm arch
+.Nd print architecture type
+.Sh SYNOPSIS
+.Nm arch
+.Sh DESCRIPTION
+The
+.Nm arch
+command displays the machine's architecture type.
+.Sh SEE ALSO
+.Xr machine 1
diff --git a/kmodstat.tproj/kmodstat.8 b/arch.tproj/machine.1
similarity index 56%
rename from kmodstat.tproj/kmodstat.8
rename to arch.tproj/machine.1
index 2353406..5c130aa 100644
--- a/kmodstat.tproj/kmodstat.8
+++ b/arch.tproj/machine.1
@@ -1,5 +1,5 @@
-.\"
-.\" Copyright (c) 1997 Doug Rabson
+.\"	$OpenBSD: machine.1,v 1.2 1996/06/26 05:36:23 deraadt Exp $
+.\" Copyright (c) 1980, 1990 The Regents of the University of California.
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -10,11 +10,18 @@
 .\" 2. Redistributions in binary form must reproduce the above copyright
 .\"    notice, this list of conditions and the following disclaimer in the
 .\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
 .\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -23,42 +30,24 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"	$Id: kmodstat.8,v 1.1.1.1 2000/01/11 02:10:18 wsanchez Exp $
+.\"	from: @(#)machine.1	5.5 (Berkeley) 7/26/91
 .\"
-.Dd April 8, 1999
-.Dt KMODSTAT 8
-.Os FreeBSD
+.Dd July 26, 1991
+.Dt MACHINE 1
+.Os
 .Sh NAME
-.Nm kmodstat
-.Nd display status of dynamically loaded kernel modules
+.Nm machine
+.Nd print machine type
 .Sh SYNOPSIS
-.Nm kmodstat
-.Op Fl i Ar id
-.Op Fl n Ar name
+.Nm machine
 .Sh DESCRIPTION
 The
-.Nm
-utility displays the status of any kernel modules dynamically
-linked into the kernel.
-.Pp
-The following options are available:
-.Bl -tag -width indentXX
-.It Fl i Ar id
-Display the status of only the kernel module with this ID.
-.It Fl n Ar name
-Display the status of only the kernel module with this name.
-.El
-.Sh DIAGNOSTICS
-The
-.Nm
-utility exits with a status of 0 on success
-and with a nonzero status if an error occurs.
+.Nm machine
+command displays the machine type.
 .Sh SEE ALSO
-.Xr kmodload 8 ,
-.Xr kmodsyms 8 ,
-.Xr kmodunload 8
+.Xr make 1
 .Sh HISTORY
 The
-.Nm
-command is based on the command kldstat written by
-.An Doug Rabson Aq dfr@FreeBSD.org
+.Nm machine
+command is
+.Ud .
diff --git a/at.tproj/Makefile.postamble b/at.tproj/Makefile.postamble
index 6f6d32b..266d5d6 100644
--- a/at.tproj/Makefile.postamble
+++ b/at.tproj/Makefile.postamble
@@ -4,3 +4,10 @@ after_install::
 	$(LN) -f $(INSTALLED_PRODUCTS) $(DSTROOT)$(INSTALLDIR)/atq
 	$(LN) -f $(INSTALLED_PRODUCTS) $(DSTROOT)$(INSTALLDIR)/atrm
 	$(LN) -f $(INSTALLED_PRODUCTS) $(DSTROOT)$(INSTALLDIR)/batch
+	mkdir -p "$(DSTROOT)/private/var/at/spool"
+	touch "$(DSTROOT)/private/var/at/at.deny"
+	mkdir -p "$(DSTROOT)/usr/share/man/man1"
+	install -c -m 644 at.1 "$(DSTROOT)/usr/share/man/man1/at.1"
+	ln -f "$(DSTROOT)/usr/share/man/man1/at.1" "$(DSTROOT)/usr/share/man/man1/atrm.1"
+	ln -f "$(DSTROOT)/usr/share/man/man1/at.1" "$(DSTROOT)/usr/share/man/man1/atq.1"
+	ln -f "$(DSTROOT)/usr/share/man/man1/at.1" "$(DSTROOT)/usr/share/man/man1/batch.1"
diff --git a/fs_usage.tproj/Makefile b/fs_usage.tproj/Makefile
index 958a48c..705acce 100644
--- a/fs_usage.tproj/Makefile
+++ b/fs_usage.tproj/Makefile
@@ -23,7 +23,7 @@ MAKEFILE = tool.make
 NEXTSTEP_INSTALLDIR = /usr/bin
 WINDOWS_INSTALLDIR = /Library/Executables
 PDO_UNIX_INSTALLDIR = /bin
-LIBS = 
+LIBS = -lcurses
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
diff --git a/fs_usage.tproj/fs_usage.1 b/fs_usage.tproj/fs_usage.1
index 67a1fba..dd06a83 100644
--- a/fs_usage.tproj/fs_usage.1
+++ b/fs_usage.tproj/fs_usage.1
@@ -1,7 +1,7 @@
 
 .\" Copyright (c) 2000, Apple Computer, Inc.  All rights reserved.
 .\"
-.Dd March 28, 2000
+.Dd November 26, 2001
 .Dt FS_USAGE 1
 .Os "Mac OS X"
 .Sh NAME
@@ -17,7 +17,7 @@ information pertaining to filesystem activity.  By default
 this includes all system processes except the running
 fs_usage process,
 Terminal, telnetd, sshd, rlogind, tcsh, csh and sh.
-These defaluts can be overridden such that output is limited to
+These defaults can be overridden such that output is limited to
 include or exclude a list of processes specified by the user.
 .Pp
 The output presented by
@@ -55,8 +55,12 @@ option has the opposite effect, excluding sampled data
 relating to the given list of process ids or commands.
 .El
 .Pp
-If "/tmp/FileTracing" is present when a Carbon Application
-is launched, then the high level Carbon FileManager
+If you set the DYLD_IMAGE_SUFFIX environment variable 
+to "_debug", then an application will use 
+the debug version of all libraries including the 
+Carbon FileManager.  See dyld(1).  When
+fs_usage is run against a Carbon Application launched
+in this environment, then the high level Carbon FileManager
 calls will be displayed bracketing the system calls that they
 are built on.
 .Pp
@@ -65,9 +69,9 @@ The data columns displayed are as follows:
 .Pp
 .It TIMESTAMP
 TOD when call occurred. Wide mode will
-have millesecond granularity.
+have millisecond granularity.
 .It CALL
-the name of the filesystem call or page-in.
+the name of the filesystem call, page-in, page-out or physical disk access.
 .It FILE DESCRIPTOR
 Of the form F=x, x is a file descriptor. Depending
 on the type of system call, this will be either
@@ -81,6 +85,9 @@ Pathname of the file accessed (up to the last 28 bytes).
 .It FAULT ADDRESS
 Of the form A=0xnnnnnnnn, where 0xnnnnnnnn is the
 address being faulted.
+.It DISK BLOCK NUMBER
+Of the form D=0xnnnnnnnn, where 0xnnnnnnnn is the block number
+of the physical disk block being read or written.
 .It TIME INTERVAL(W)
 The elapsed time spent in the system call.
 A 'W' after the elapsed time indicates
@@ -103,3 +110,4 @@ data output will be displayed in the window.
 .Xr top 1
 .Xr sc_usage 1
 .Xr latency 1
+.Xr dyld 1
diff --git a/fs_usage.tproj/fs_usage.c b/fs_usage.tproj/fs_usage.c
index 465d0dc..c41e3f0 100644
--- a/fs_usage.tproj/fs_usage.c
+++ b/fs_usage.tproj/fs_usage.c
@@ -35,6 +35,7 @@ cc -I. -DKERNEL_PRIVATE -O -o fs_usage fs_usage.c
 #include <nlist.h>
 #include <fcntl.h>
 #include <string.h>
+#include <dirent.h>
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -42,7 +43,6 @@ cc -I. -DKERNEL_PRIVATE -O -o fs_usage fs_usage.c
 
 #include <libc.h>
 #include <termios.h>
-#include <bsd/curses.h>
 #include <sys/ioctl.h>
 
 #ifndef KERNEL_PRIVATE
@@ -60,6 +60,23 @@ cc -I. -DKERNEL_PRIVATE -O -o fs_usage fs_usage.c
 
 extern int errno;
 
+
+
+#define MAXINDEX 2048
+
+typedef struct LibraryInfo {
+     unsigned long address;
+     char     *name;
+} LibraryInfo;
+
+LibraryInfo frameworkInfo[MAXINDEX];
+int numFrameworks = 0;
+
+char seg_addr_table[256]="/AppleInternal/Developer/seg_addr_table";
+
+char *lookup_name();
+
+
 /* 
    MAXCOLS controls when extra data kicks in.
    MAX_WIDE_MODE_COLS controls -w mode to get even wider data in path.
@@ -94,12 +111,49 @@ int  cur_max = 0;
 int  need_new_map = 1;
 int  bias_secs;
 int  wideflag = 0;
+int  columns = 0;
 int  select_pid_mode = 0;  /* Flag set indicates that output is restricted
 			      to selected pids or commands */
 
 int  one_good_pid = 0;    /* Used to fail gracefully when bad pids given */
 
 
+#define NFS_DEV -1
+
+struct diskrec {
+        struct diskrec *next;
+        char *diskname;
+        int   dev;
+};
+
+struct diskio {
+        struct diskio *next;
+        struct diskio *prev;
+        int  type;
+        int  bp;
+        int  dev;
+        int  blkno;
+        int  iosize;
+        int  io_errno;
+        int  issuing_thread;
+        int  completion_thread;
+        char issuing_command[MAXCOMLEN];
+        double issued_time;
+        double completed_time;
+};
+
+struct diskrec *disk_list = NULL;
+struct diskio *free_diskios = NULL;
+struct diskio *busy_diskios = NULL;
+
+struct diskio *insert_diskio();
+struct diskio *complete_diskio();
+void    	free_diskio();
+void		print_diskio();
+void		format_print();
+char           *find_disk_name();
+
+
 #define DBG_ZERO_FILL_FAULT   1
 #define DBG_PAGEIN_FAULT      2
 #define DBG_COW_FAULT         3
@@ -110,11 +164,39 @@ int  one_good_pid = 0;    /* Used to fail gracefully when bad pids given */
 #define TRACE_STRING_EXEC      0x07010008
 
 #define MACH_vmfault    0x01300000
+#define MACH_pageout    0x01300004
 #define MACH_sched      0x01400000
 #define MACH_stkhandoff 0x01400008
 #define VFS_LOOKUP      0x03010090
 #define BSC_exit        0x040C0004
 
+#define P_WrData	0x03020000
+#define P_RdData	0x03020008
+#define P_WrMeta	0x03020020
+#define P_RdMeta	0x03020028
+#define P_PgOut		0x03020040
+#define P_PgIn		0x03020048
+#define P_WrDataAsync	0x03020010
+#define P_RdDataAsync	0x03020018
+#define P_WrMetaAsync	0x03020030
+#define P_RdMetaAsync	0x03020038
+#define P_PgOutAsync	0x03020050
+#define P_PgInAsync	0x03020058
+
+#define P_WrDataDone	0x03020004
+#define P_RdDataDone	0x0302000C
+#define P_WrMetaDone	0x03020024
+#define P_RdMetaDone	0x0302002C
+#define P_PgOutDone	0x03020044
+#define P_PgInDone	0x0302004C
+#define P_WrDataAsyncDone	0x03020014
+#define P_RdDataAsyncDone	0x0302001C
+#define P_WrMetaAsyncDone	0x03020034
+#define P_RdMetaAsyncDone	0x0302003C
+#define P_PgOutAsyncDone	0x03020054
+#define P_PgInAsyncDone		0x0302005C
+
+
 #define MSC_map_fd   0x010c00ac
 #define	BSC_recvmsg  0x040C006C
 #define	BSC_sendmsg  0x040C0070
@@ -127,23 +209,30 @@ int  one_good_pid = 0;    /* Used to fail gracefully when bad pids given */
 #define BSC_close    0x040C0018
 #define BSC_link     0x040C0024
 #define BSC_unlink   0x040C0028
+#define BSC_chdir    0x040c0030
+#define BSC_fchdir   0x040c0034
 #define BSC_mknod    0x040C0038	
 #define BSC_chmod    0x040C003C	
 #define BSC_chown    0x040C0040	
 #define BSC_access   0x040C0084	
 #define BSC_chflags  0x040C0088	
 #define BSC_fchflags 0x040C008C
-#define BSC_sync     0x040C0090	
+#define BSC_sync     0x040C0090
+#define BSC_revoke   0x040C00E0
 #define BSC_symlink  0x040C00E4	
-#define BSC_readlink 0x040C00E8	
+#define BSC_readlink 0x040C00E8
+#define BSC_chroot   0x040C00F4	
 #define BSC_fsync    0x040C017C	
 #define BSC_readv    0x040C01E0	
 #define BSC_writev   0x040C01E4	
 #define BSC_fchown   0x040C01EC	
 #define BSC_fchmod   0x040C01F0	
-#define BSC_rename   0x040C0200	
+#define BSC_rename   0x040C0200
+#define BSC_mkfifo   0x040c0210	
 #define BSC_mkdir    0x040C0220	
-#define BSC_rmdir    0x040C0224	
+#define BSC_rmdir    0x040C0224
+#define BSC_utimes   0x040C0228
+#define BSC_futimes  0x040C022C
 #define BSC_statfs   0x040C0274	
 #define BSC_fstatfs  0x040C0278	
 #define BSC_stat     0x040C02F0	
@@ -155,17 +244,22 @@ int  one_good_pid = 0;    /* Used to fail gracefully when bad pids given */
 #define BSC_mmap     0x040c0314
 #define BSC_lseek    0x040c031c
 #define BSC_truncate 0x040C0320
-#define BSC_ftruncate     0x040C0324	
+#define BSC_ftruncate     0x040C0324
+#define BSC_undelete 0x040C0334
 #define BSC_statv    0x040C0364	
 #define BSC_lstatv   0x040C0368	
 #define BSC_fstatv   0x040C036C	
-#define BSC_mkcomplex     0x040C0360	
+#define BSC_mkcomplex   0x040C0360	
 #define BSC_getattrlist 0x040C0370	
 #define BSC_setattrlist 0x040C0374	
 #define BSC_getdirentriesattr 0x040C0378	
 #define BSC_exchangedata  0x040C037C	
 #define BSC_checkuseraccess   0x040C0380	
-#define BSC_searchfs    0x040C0384	
+#define BSC_searchfs    0x040C0384
+#define BSC_delete      0x040C0388
+#define BSC_copyfile    0x040C038C
+#define BSC_fsctl       0x040C03C8
+#define BSC_load_shared_file  0x040C04A0
 
 // Carbon File Manager support
 #define FILEMGR_PBGETCATALOGINFO		 0x1e000020
@@ -259,9 +353,7 @@ int kp_nentries = 0;
 #define DBG_FUNC_ALL	(DBG_FUNC_START | DBG_FUNC_END)
 #define DBG_FUNC_MASK	0xfffffffc
 
-/* Default divisor */
-#define DIVISOR 16.6666        /* Trace divisor converts to microseconds */
-double divisor = DIVISOR;
+double divisor = 0.0;       /* Trace divisor converts to microseconds */
 
 int mib[6];
 size_t needed;
@@ -308,10 +400,23 @@ void leave()			/* exit under normal conditions -- INT handler */
 }
 
 
+void get_screenwidth()
+{
+        struct winsize size;
+
+	columns = MAXCOLS;
+
+	if (isatty(1)) {
+	        if (ioctl(1, TIOCGWINSZ, &size) != -1)
+		        columns = size.ws_col;
+	}
+}
+
+
 void sigwinch()
 {
-  if (!wideflag)
-    initscr();
+        if (!wideflag)
+	        get_screenwidth();
 }
 
 int
@@ -349,8 +454,7 @@ main(argc, argv)
             printf("'fs_usage' must be run as root...\n");
             exit(1);
         }
-
-	initscr();
+	get_screenwidth();
 
 	/* get our name */
 	if (argc > 0) {
@@ -370,8 +474,8 @@ main(argc, argv)
 		    break;
                 case 'w':
 		    wideflag = 1;
-		    if (COLS < MAX_WIDE_MODE_COLS)
-		      COLS = MAX_WIDE_MODE_COLS;
+		    if (columns < MAX_WIDE_MODE_COLS)
+		      columns = MAX_WIDE_MODE_COLS;
 		    break;
 	       default:
 		 exit_usage(myname);		 
@@ -397,6 +501,7 @@ main(argc, argv)
 	  {
 	    argtopid("Terminal");
 	    argtopid("telnetd");
+	    argtopid("telnet");
 	    argtopid("sshd");
 	    argtopid("rlogind");
 	    argtopid("tcsh");
@@ -426,12 +531,16 @@ main(argc, argv)
 	/* set up signal handlers */
 	signal(SIGINT, leave);
 	signal(SIGQUIT, leave);
+	signal(SIGHUP, leave);
 	signal(SIGTERM, leave);
 	signal(SIGWINCH, sigwinch);
 
 	if ((my_buffer = malloc(SAMPLE_SIZE * sizeof(kd_buf))) == (char *)0)
 	    quit("can't allocate memory for tracing info\n");
 
+	ReadSegAddrTable();
+        cache_disk_names();
+
 	set_remove();
 	set_numbufs(SAMPLE_SIZE);
 	set_init();
@@ -461,7 +570,7 @@ main(argc, argv)
 	/* main loop */
 
 	while (1) {
-	        usleep(1000 * 50);
+	        usleep(1000 * 25);
 
 		sample_sc();
 	}
@@ -470,7 +579,7 @@ main(argc, argv)
 void
 find_proc_names()
 {
-	size_t			bufSize = 0;
+        size_t			bufSize = 0;
 	struct kinfo_proc       *kp;
 	int quit();
 
@@ -512,6 +621,18 @@ struct th_info *find_thread(int thread, int type) {
        return ((struct th_info *)0);
 }
 
+
+mark_thread_waited(int thread) {
+       struct th_info *ti;
+
+       for (ti = th_state; ti < &th_state[cur_max]; ti++) {
+	       if (ti->thread == thread) {
+                    ti->waited = 1;
+	       }
+       }
+}
+
+
 void
 set_enable(int val) 
 {
@@ -624,8 +745,6 @@ get_bufinfo(kbufinfo_t *val)
 void
 set_remove() 
 {
-        extern int errno;
-
         errno = 0;
 
 	mib[0] = CTL_KERN;
@@ -726,6 +845,7 @@ sample_sc()
 		long *sargptr;
 		unsigned long long now;
 		struct th_info *ti;
+                struct diskio  *dio;
 		void enter_syscall();
 		void exit_syscall();
 		void kill_thread_map();
@@ -733,9 +853,47 @@ sample_sc()
 		thread  = kd[i].arg5 & KDBG_THREAD_MASK;
 		debugid = kd[i].debugid;
 		type    = kd[i].debugid & DBG_FUNC_MASK;
+                
+                now = (((unsigned long long)kd[i].timestamp.tv_sec) << 32) |
+                        (unsigned long long)((unsigned int)(kd[i].timestamp.tv_nsec));
+
 
 		switch (type) {
 
+                case P_RdMeta:
+                case P_WrMeta:
+                case P_RdData:
+                case P_WrData:
+                case P_PgIn:
+                case P_PgOut:
+                case P_RdMetaAsync:
+                case P_WrMetaAsync:
+                case P_RdDataAsync:
+                case P_WrDataAsync:
+                case P_PgInAsync:
+                case P_PgOutAsync:
+                    insert_diskio(type, kd[i].arg1, kd[i].arg2, kd[i].arg3, kd[i].arg4, thread, (double)now);
+                    continue;
+                
+                case P_RdMetaDone:
+                case P_WrMetaDone:
+                case P_RdDataDone:
+                case P_WrDataDone:
+                case P_PgInDone:
+                case P_PgOutDone:
+                case P_RdMetaAsyncDone:
+                case P_WrMetaAsyncDone:
+                case P_RdDataAsyncDone:
+                case P_WrDataAsyncDone:
+                case P_PgInAsyncDone:
+                case P_PgOutAsyncDone:
+                    if (dio = complete_diskio(kd[i].arg1, kd[i].arg4, kd[i].arg3, thread, (double)now)) {
+                        print_diskio(dio);
+                        free_diskio(dio);
+                    }
+                    continue;
+
+
 		case TRACE_DATA_NEWTHREAD:
 		   
 		    for (n = 0, ti = th_state; ti < &th_state[MAX_THREADS]; ti++, n++) {
@@ -774,8 +932,7 @@ sample_sc()
 
 		case MACH_sched:
 		case MACH_stkhandoff:
-		    if (ti = find_thread(thread, 0))
-		            ti->waited = 1;
+                    mark_thread_waited(thread);
 		    continue;
 
 		case VFS_LOOKUP:
@@ -789,7 +946,6 @@ sample_sc()
 			    *sargptr++ = kd[i].arg3;
 			    *sargptr++ = kd[i].arg4;
 			    ti->pathptr = sargptr;
-
 		    } else {
 		            sargptr = ti->pathptr;
 
@@ -802,6 +958,19 @@ sample_sc()
 			    if ((long *)sargptr >= (long *)&ti->pathname[PATHLENGTH])
 			      continue;
 
+                            /*
+			      We need to detect consecutive vfslookup entries.
+			      So, if we get here and find a START entry,
+			      fake the pathptr so we can bypass all further
+			      vfslookup entries.
+			    */
+
+			    if (debugid & DBG_FUNC_START)
+			      {
+				(long *)ti->pathptr = (long *)&ti->pathname[PATHLENGTH];
+				continue;
+			      }
+
 			    *sargptr++ = kd[i].arg1;
 			    *sargptr++ = kd[i].arg2;
 			    *sargptr++ = kd[i].arg3;
@@ -810,8 +979,6 @@ sample_sc()
 		    }
 		    continue;
 		}
-		now = (((unsigned long long)kd[i].timestamp.tv_sec) << 32) |
-		        (unsigned long long)((unsigned int)(kd[i].timestamp.tv_nsec));
 
 		if (debugid & DBG_FUNC_START) {
 		       char *p;
@@ -1025,9 +1192,18 @@ sample_sc()
 		}
 		switch (type) {
 
+		case MACH_pageout:
+		    if (kd[i].arg2) 
+		            exit_syscall("PAGE_OUT_D", thread, type, 0, kd[i].arg1, 0, 4, (double)now);
+		    else
+		            exit_syscall("PAGE_OUT_V", thread, type, 0, kd[i].arg1, 0, 4, (double)now);
+		    break;
+
 		case MACH_vmfault:
 		    if (kd[i].arg2 == DBG_PAGEIN_FAULT)
-		            exit_syscall("PAGE_IN", thread, type, 0, kd[i].arg1, 0, 2, (double)now);
+		            exit_syscall("PAGE_IN", thread, type, kd[i].arg4, kd[i].arg1, 0, 6, (double)now);
+                    else if (kd[i].arg2 == DBG_CACHE_HIT_FAULT)
+		            exit_syscall("CACHE_HIT", thread, type, 0, kd[i].arg1, 0, 2, (double)now);
 		    else {
 		            if (ti = find_thread(thread, type)) {
 			            if (ti == &th_state[cur_max - 1])
@@ -1064,6 +1240,10 @@ sample_sc()
 		case BSC_stat:
 		    exit_syscall("stat", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
 		    break;
+                    
+		case BSC_load_shared_file:
+		    exit_syscall("load_sf", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
 
 		case BSC_open:
 		    exit_syscall("open", thread, type, kd[i].arg1, kd[i].arg2, 2, 0, (double)now);
@@ -1113,13 +1293,49 @@ sample_sc()
 		    exit_syscall("access", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
 		    break;
 
+		case BSC_chdir:
+		    exit_syscall("chdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
+                    
+		case BSC_chroot:
+		    exit_syscall("chroot", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
+                    
+		case BSC_utimes:
+		    exit_syscall("utimes", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
+                    
+		case BSC_delete:
+		    exit_syscall("delete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
+                    
+		case BSC_undelete:
+		    exit_syscall("undelete", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
+                    
+		case BSC_revoke:
+		    exit_syscall("revoke", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
+                    
+		case BSC_fsctl:
+		    exit_syscall("fsctl", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
+                    
 		case BSC_chflags:
 		    exit_syscall("chflags", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
 		    break;
-
+                    
 		case BSC_fchflags:
 		    exit_syscall("fchflags", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
 		    break;
+                    
+		case BSC_fchdir:
+		    exit_syscall("fchdir", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
+		    break;
+                    
+		case BSC_futimes:
+		    exit_syscall("futimes", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
+		    break;
 
 		case BSC_sync:
 		    exit_syscall("sync", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
@@ -1153,13 +1369,13 @@ sample_sc()
 		    exit_syscall("fchmod", thread, type, kd[i].arg1, kd[i].arg2, 1, 0, (double)now);
 		    break;
 
-		case BSC_rename:
-		    exit_syscall("rename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
-		    break;
-
 		case BSC_mkdir:
 		    exit_syscall("mkdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
 		    break;
+                    
+		case BSC_mkfifo:
+		    exit_syscall("mkfifo", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
 
 		case BSC_rmdir:
 		    exit_syscall("rmdir", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
@@ -1225,9 +1441,19 @@ sample_sc()
 		    exit_syscall("getdirentriesattr", thread, type, kd[i].arg1, kd[i].arg2, 0, 1, (double)now);
 		    break;
 
+
 		case BSC_exchangedata:
 		    exit_syscall("exchangedata", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
 		    break;
+                    
+ 		case BSC_rename:
+		    exit_syscall("rename", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
+
+ 		case BSC_copyfile:
+		    exit_syscall("copyfile", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
+		    break;
+
 
 		case BSC_checkuseraccess:
 		    exit_syscall("checkuseraccess", thread, type, kd[i].arg1, kd[i].arg2, 0, 0, (double)now);
@@ -1461,6 +1687,7 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
 
        switch (type) {
 
+       case MACH_pageout:
        case MACH_vmfault:
        case MSC_map_fd:
        case BSC_mmap:
@@ -1469,6 +1696,7 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
        case BSC_recvfrom:
        case BSC_sendto:
        case BSC_stat:
+       case BSC_load_shared_file:
        case BSC_open:
        case BSC_close:
        case BSC_read:
@@ -1483,6 +1711,16 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
        case BSC_access:
        case BSC_chflags:
        case BSC_fchflags:
+       case BSC_fchdir:
+       case BSC_futimes:
+       case BSC_chdir:
+       case BSC_utimes:
+       case BSC_chroot:
+       case BSC_undelete:
+       case BSC_delete:
+       case BSC_revoke:
+       case BSC_fsctl:
+       case BSC_copyfile:
        case BSC_sync:
        case BSC_symlink:
        case BSC_readlink:
@@ -1493,6 +1731,7 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
        case BSC_fchmod:
        case BSC_rename:
        case BSC_mkdir:
+       case BSC_mkfifo:
        case BSC_rmdir:
        case BSC_statfs:
        case BSC_fstatfs:
@@ -1589,6 +1828,7 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
 	           return;
 	   if (i >= cur_max)
 	           cur_max = i + 1;
+                   
 
 	   if ((type >> 24) == FILEMGR_CLASS) {
 		   ti->in_filemgr = 1;
@@ -1604,7 +1844,7 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
 		   sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
 		   tsclen = strlen(buf);
 
-		   if (COLS > MAXCOLS || wideflag) {
+		   if (columns > MAXCOLS || wideflag) {
 		           usecs = l_usecs - (long long)((long long)secs * 1000000);
 			   sprintf(&buf[tsclen], ".%03ld", (long)usecs / 1000);
 			   tsclen = strlen(buf);
@@ -1625,12 +1865,12 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
 		       /*
 			 Calculate white space out to command
 		       */
-		       if (COLS > MAXCOLS || wideflag)
+		       if (columns > MAXCOLS || wideflag)
 			 {
-			   clen = COLS - (tsclen + nmclen + argsclen + 20);
+			   clen = columns - (tsclen + nmclen + argsclen + 20);
 			 }
 		       else
-			 clen = COLS - (tsclen + nmclen + argsclen + 12);
+			 clen = columns - (tsclen + nmclen + argsclen + 12);
 
 		       if(clen > 0)
 			 {
@@ -1647,7 +1887,7 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
 			   printf(buf);
 			 }
 
-		       if (COLS > MAXCOLS || wideflag)
+		       if (columns > MAXCOLS || wideflag)
 			   printf("%-20.20s\n", map->command); 
 		       else
 			   printf("%-12.12s\n", map->command); 
@@ -1666,7 +1906,6 @@ enter_syscall(int thread, int type, kd_buf *kd, char *name, double now)
 	   ti->arg4   = kd->arg4;
 	   ti->pathptr = (long *)0;
 	   ti->pathname[0] = 0;
-
 	   break;
 
        default:
@@ -1680,21 +1919,45 @@ void
 exit_syscall(char *sc_name, int thread, int type, int error, int retval,
 	                    int has_fd, int has_ret, double now)
 {
-       struct th_info *ti;
+    struct th_info *ti;
+      
+    if ((ti = find_thread(thread, type)) == (struct th_info *)0)
+        return;
+               
+    format_print(ti, sc_name, thread, type, error, retval, has_fd, has_ret, now, ti->stime, ti->waited, ti->pathname, NULL);
+
+    if (ti == &th_state[cur_max - 1])
+        cur_max--;
+    ti->thread = 0;
+}
+
+
+
+void
+format_print(struct th_info *ti, char *sc_name, int thread, int type, int error, int retval,
+	                    int has_fd, int has_ret, double now, double stime, int waited, char *pathname, struct diskio *dio)
+{
        int secs;
        int usecs;
        int nopadding;
        long long l_usecs;
        long curr_time;
+       char *command_name;
        kd_threadmap *map;
        kd_threadmap *find_thread_map();
        int len = 0;
        int clen = 0;
+       char *framework_name;
        char buf[MAXCOLS];
       
-       if ((ti = find_thread(thread, type)) == (struct th_info *)0)
-	       return;
-       map = find_thread_map(thread);
+       command_name = "";
+       
+       if (dio)
+            command_name = dio->issuing_command;
+       else {
+            if (map = find_thread_map(thread))
+                command_name = map->command;
+       }
        l_usecs = (long long)(now / divisor);
        secs = l_usecs / 1000000;
 
@@ -1706,11 +1969,12 @@ exit_syscall(char *sc_name, int thread, int type, int error, int retval,
        sprintf(buf, "%-8.8s", &(ctime(&curr_time)[11]));
        clen = strlen(buf);
 
-       if (COLS > MAXCOLS || wideflag) {
+       if (columns > MAXCOLS || wideflag) {
 	       nopadding = 0;
 	       usecs = l_usecs - (long long)((long long)secs * 1000000);
 	       sprintf(&buf[clen], ".%03ld", (long)usecs / 1000);
 	       clen = strlen(buf);
+               
 	       if ((type >> 24) != FILEMGR_CLASS) {
 		   if (find_thread(thread, -1)) {
 		       sprintf(&buf[clen], "   ");
@@ -1721,53 +1985,75 @@ exit_syscall(char *sc_name, int thread, int type, int error, int retval,
        } else
 	       nopadding = 1;
 
-       if (((type >> 24) == FILEMGR_CLASS) && (COLS > MAXCOLS || wideflag))
+       if (((type >> 24) == FILEMGR_CLASS) && (columns > MAXCOLS || wideflag))
 	       sprintf(&buf[clen], "  %-18.18s", sc_name);
        else
 	       sprintf(&buf[clen], "  %-15.15s", sc_name);
 
        clen = strlen(buf);
-
-       if (COLS > MAXCOLS || wideflag) {
+       
+       framework_name = (char *)0;
+
+       if (columns > MAXCOLS || wideflag) {
+            if (has_ret == 7) {
+                sprintf(&buf[clen], " D=0x%8.8x", dio->blkno);
+                
+                clen = strlen(buf);
+                
+                if (dio->io_errno)
+                    sprintf(&buf[clen], "  [%3d]       ", dio->io_errno);
+                else
+                    sprintf(&buf[clen], "  B=0x%-6x   /dev/%s", dio->iosize, find_disk_name(dio->dev));
+            } else {
+              
 	       if (has_fd == 2 && error == 0)
 		       sprintf(&buf[clen], " F=%-3d", retval);
 	       else if (has_fd == 1)
 		       sprintf(&buf[clen], " F=%-3d", ti->arg1);
-	       else if (has_ret != 2)
+	       else if (has_ret != 2 && has_ret != 6)
 		       sprintf(&buf[clen], "      ");
 
 	       clen = strlen(buf);
 
-	       if (error)
+	       if (has_ret == 2 || has_ret == 6)
+		       framework_name = lookup_name(retval);
+
+	       if (error && has_ret != 6)
 		       sprintf(&buf[clen], "[%3d]       ", error);
 	       else if (has_ret == 3)
 		       sprintf(&buf[clen], "O=0x%8.8x", ti->arg3);
 	       else if (has_ret == 5)
 		       sprintf(&buf[clen], "O=0x%8.8x", retval);
 	       else if (has_ret == 2) 
-		       sprintf(&buf[clen], " A=0x%8.8x     ", retval);
+		       sprintf(&buf[clen], " A=0x%8.8x              ", retval);
+	       else if (has_ret == 6) 
+		       sprintf(&buf[clen], " A=0x%8.8x  B=0x%-8x", retval, error);
 	       else if (has_ret == 1)
 		       sprintf(&buf[clen], "  B=0x%-6x", retval);
 	       else if (has_ret == 4)
-		       sprintf(&buf[clen], "R=0x%-8x", retval);
+		       sprintf(&buf[clen], "B=0x%-8x", retval);
 	       else
 		       sprintf(&buf[clen], "            ");
-	       clen = strlen(buf);
+            }
+            clen = strlen(buf);
        }
        printf(buf);
 
        /*
 	 Calculate space available to print pathname
        */
-       if (COLS > MAXCOLS || wideflag)
-	 clen =  COLS - (clen + 13 + 20);
+       if (columns > MAXCOLS || wideflag)
+	 clen =  columns - (clen + 13 + 20);
        else
-	 clen =  COLS - (clen + 13 + 12);
+	 clen =  columns - (clen + 13 + 12);
 
        if ((type >> 24) != FILEMGR_CLASS && !nopadding)
 	 clen -= 3;
 
-       sprintf(&buf[0], " %s ", ti->pathname);
+       if (framework_name)
+	 sprintf(&buf[0], " %s ", framework_name);
+       else
+	 sprintf(&buf[0], " %s ", pathname);
        len = strlen(buf);
        
        if (clen > len)
@@ -1791,30 +2077,26 @@ exit_syscall(char *sc_name, int thread, int type, int error, int retval,
 	   printf(&buf[len - clen]);
 	 }
 
-       usecs = (unsigned long)(((double)now - ti->stime) / divisor);
+       usecs = (unsigned long)((now - stime) / divisor);
        secs = usecs / 1000000;
        usecs -= secs * 1000000;
 
        if ((type >> 24) != FILEMGR_CLASS && !nopadding)
 	       printf("   ");
 	       
-       printf(" %2ld.%06ld", (long)secs, (long)usecs);
-       if (ti->waited)
+       printf(" %2ld.%06ld", (unsigned long)secs, (unsigned long)usecs);
+       
+       if (waited)
 	       printf(" W");
        else
 	       printf("  ");
 
-       if (map) {
-	       if (COLS > MAXCOLS || wideflag)
-		       printf(" %-20.20s", map->command);
-	       else
-		       printf(" %-12.12s", map->command);
-       }
-       printf("\n");
+       if (columns > MAXCOLS || wideflag)
+               printf(" %-20.20s", command_name);
+       else
+               printf(" %-12.12s", command_name);
 
-       if (ti == &th_state[cur_max - 1])
-	         cur_max--;
-       ti->thread = 0;
+       printf("\n");
        fflush (0);
 }
 
@@ -1849,7 +2131,7 @@ void getdivisor()
     unsigned int proc_to_abs_num;
     unsigned int proc_to_abs_denom;
 
-	extern void MKGetTimeBaseInfo(unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *);
+    extern void MKGetTimeBaseInfo(unsigned int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *);
 
     MKGetTimeBaseInfo (&delta, &abs_to_ns_num, &abs_to_ns_denom,
 		       &proc_to_abs_num,  &proc_to_abs_denom);
@@ -1875,10 +2157,7 @@ void read_command_map()
         if (mapptr = (kd_threadmap *) malloc(size))
 	     bzero (mapptr, size);
 	else
-	{
-	    printf("Thread map is not initialized -- this is not fatal\n");
 	    return;
-	}
     }
  
     /* Now read the threadmap */
@@ -1891,13 +2170,9 @@ void read_command_map()
     if (sysctl(mib, 3, mapptr, &size, NULL, 0) < 0)
     {
         /* This is not fatal -- just means I cant map command strings */
-
-        printf("Can't read the thread map -- this is not fatal\n");
 	free(mapptr);
 	mapptr = 0;
-	return;
     }
-    return;
 }
 
 
@@ -2012,3 +2287,376 @@ argtopid(str)
 }
 
 
+
+char *lookup_name(unsigned long addr) 
+{       
+        register int i;
+	register int start, last;
+
+
+	if (numFrameworks == 0 || addr < frameworkInfo[0].address || addr > frameworkInfo[numFrameworks].address)
+	        return (0);
+
+	start = 0;
+	last  = numFrameworks;
+
+	for (i = numFrameworks / 2; i >= 0 && i < numFrameworks; ) {
+
+	        if (addr >= frameworkInfo[i].address && addr < frameworkInfo[i+1].address)
+		        return(frameworkInfo[i].name);
+
+		if (addr >= frameworkInfo[i].address) {
+		        start = i;
+		        i = start + ((last - i) / 2);
+		} else {
+		        last = i;
+		        i = start + ((i - start) / 2);
+		}
+	}
+	return (0);
+}
+
+
+/*
+ * Comparison routines for sorting
+ */
+static int compareFrameworkAddress(const void  *aa, const void *bb)
+{
+    LibraryInfo *a = (LibraryInfo *)aa;
+    LibraryInfo *b = (LibraryInfo *)bb;
+
+    if (a->address < b->address) return -1;
+    if (a->address == b->address) return 0;
+    return 1;
+}
+
+
+int scanline(char *inputstring,char **argv)
+{
+     int n = 0;
+     char **ap = argv, *p, *val;  
+
+     for (p = inputstring; p != NULL; ) 
+     {
+        while ((val = strsep(&p, " \t")) != NULL && *val == '\0');
+        *ap++ = val;
+        n++; 
+     }
+     *ap = 0;
+     return n;
+}
+
+
+int ReadSegAddrTable()
+{
+    char buf[1024];
+
+    FILE *fd;
+    unsigned long frameworkAddress, frameworkDataAddress, previousFrameworkAddress;
+    char frameworkName[256];
+    char *tokens[64];
+    int  ntokens;
+    char *substring,*ptr;
+    int  founddylib = 0;
+    int  i;
+
+
+    bzero(buf, sizeof(buf));
+    bzero(tokens, sizeof(tokens));
+    
+    numFrameworks = 0;
+
+    if ((fd = fopen(seg_addr_table, "r")) == 0)
+    {
+        return 0;
+    }
+    fgets(buf, 1023, fd);
+
+    if (*buf == '#')
+    {
+        founddylib = 0;
+        frameworkName[0] = 0;
+        previousFrameworkAddress = 0;
+
+        while (fgets(buf, 1023, fd) && numFrameworks < (MAXINDEX - 2))
+        {
+	    /*
+	     * Get rid of EOL
+	     */
+	    buf[strlen(buf)-1] = 0;
+
+	    if (strncmp(buf, "# dyld:", 7) == 0) {
+	        /*
+		 * the next line in the file will contain info about dyld
+		 */
+	        founddylib = 1;
+		continue;
+	    }
+	    /*
+	     * This is a split library line: parse it into 3 tokens
+	     */
+	    ntokens = scanline(buf, tokens);
+
+	    if (ntokens < 3)
+	        continue;
+
+	    frameworkAddress     = strtoul(tokens[0], 0, 16);
+	    frameworkDataAddress = strtoul(tokens[1], 0, 16);
+
+	    if (founddylib) {
+	        /*
+		 * dyld entry is of a different form from the std split library
+		 * it consists of a base address and a size instead of a code
+		 * and data base address
+		 */
+	        frameworkInfo[numFrameworks].address   = frameworkAddress;
+		frameworkInfo[numFrameworks+1].address = frameworkAddress + frameworkDataAddress;
+
+		frameworkInfo[numFrameworks].name   = (char *)"dylib";
+		frameworkInfo[numFrameworks+1].name = (char *)0;
+
+		numFrameworks += 2;
+		founddylib = 0;
+
+		continue;
+	    }  
+
+	    /*
+	     * Make sure that we have 2 addresses and a path
+	     */
+	    if (!frameworkAddress)
+	        continue;
+	    if (!frameworkDataAddress)
+	        continue;
+	    if (*tokens[2] != '/')
+	        continue;
+	    if (frameworkAddress == previousFrameworkAddress) 
+	        continue;
+	    previousFrameworkAddress = frameworkAddress;
+
+            /*
+	     * Extract lib name from path name
+	     */
+	    if (substring = strrchr(tokens[2], '.'))
+	    {		
+	        /*
+		 * There is a ".": name is whatever is between the "/" around the "." 
+		 */
+	      while ( *substring != '/') {		    /* find "/" before "." */
+		    substring--;
+		}
+		substring++;
+		strcpy(frameworkName, substring);           /* copy path from "/" */
+		substring = frameworkName;
+
+		while ( *substring != '/' && *substring)    /* find "/" after "." and stop string there */
+		    substring++;
+		*substring = 0;
+	    }
+	    else 
+	    {
+	        /*
+		 * No ".": take segment after last "/"
+		 */
+	        ptr = tokens[2];
+		substring = ptr;
+
+		while (*ptr) 
+		{
+		    if (*ptr == '/')
+		        substring = ptr + 1;
+		    ptr++;
+		}
+		strcpy(frameworkName, substring);
+	    }
+	    frameworkInfo[numFrameworks].address   = frameworkAddress;
+	    frameworkInfo[numFrameworks+1].address = frameworkDataAddress;
+
+	    frameworkInfo[numFrameworks].name = (char *)malloc(strlen(frameworkName) + 1);
+	    strcpy(frameworkInfo[numFrameworks].name, frameworkName);
+	    frameworkInfo[numFrameworks+1].name = frameworkInfo[numFrameworks].name;
+
+	    numFrameworks += 2;
+        }
+    }
+    frameworkInfo[numFrameworks].address = frameworkInfo[numFrameworks - 1].address + 0x800000;
+    frameworkInfo[numFrameworks].name = (char *)0;
+
+    fclose(fd);
+
+    qsort(frameworkInfo, numFrameworks, sizeof(LibraryInfo), compareFrameworkAddress);
+
+    return 1;
+}
+
+
+struct diskio *insert_diskio(int type, int bp, int dev, int blkno, int io_size, int thread, double curtime)
+{
+    register struct diskio *dio;
+    register kd_threadmap  *map;
+    
+    if (dio = free_diskios)
+        free_diskios = dio->next;
+    else {
+        if ((dio = (struct diskio *)malloc(sizeof(struct diskio))) == NULL)
+            return (NULL);
+    }
+    dio->prev = NULL;
+    
+    dio->type = type;
+    dio->bp = bp;
+    dio->dev = dev;
+    dio->blkno = blkno;
+    dio->iosize = io_size;
+    dio->issued_time = curtime;
+    dio->issuing_thread = thread;
+    
+    if (map = find_thread_map(thread))
+        strcpy(dio->issuing_command, map->command);
+    else
+        strcpy(dio->issuing_command, "");
+    
+    dio->next = busy_diskios;
+    if (dio->next)
+        dio->next->prev = dio;
+    busy_diskios = dio;
+
+    return (dio);
+}
+
+
+struct diskio *complete_diskio(int bp, int io_errno, int resid, int thread, double curtime)
+{
+    register struct diskio *dio;
+    
+    for (dio = busy_diskios; dio; dio = dio->next) {
+        if (dio->bp == bp) {
+        
+            if (dio == busy_diskios) {
+                if (busy_diskios = dio->next)
+                    dio->next->prev = NULL;
+            } else {
+                if (dio->next)
+                    dio->next->prev = dio->prev;
+                dio->prev->next = dio->next;
+            }
+            dio->iosize -= resid;
+            dio->io_errno = io_errno;
+            dio->completed_time = curtime;
+            dio->completion_thread = thread;
+            
+	    return (dio);
+        }    
+    }
+    return ((struct diskio *)0);
+}
+
+
+void free_diskio(struct diskio *dio)
+{
+    dio->next = free_diskios;
+    free_diskios = dio;
+}
+
+
+void print_diskio(struct diskio *dio)
+{
+    register char  *p;
+    struct th_info *ti;
+
+    switch (dio->type) {
+
+        case P_RdMeta:
+            p = "  RdMeta";
+            break;
+        case P_WrMeta:
+            p = "  WrMeta";
+            break;
+        case P_RdData:
+            p = "  RdData";
+            break;
+        case P_WrData:
+            p = "  WrData";
+            break;        
+        case P_PgIn:
+            p = "  PgIn";
+            break;
+        case P_PgOut:
+            p = "  PgOut";
+            break;
+        case P_RdMetaAsync:
+            p = "  RdMeta[async]";
+            break;
+        case P_WrMetaAsync:
+            p = "  WrMeta[async]";
+            break;
+        case P_RdDataAsync:
+            p = "  RdData[async]";
+            break;
+        case P_WrDataAsync:
+            p = "  WrData[async]";
+            break;        
+        case P_PgInAsync:
+            p = "  PgIn[async]";
+            break;
+        case P_PgOutAsync:
+            p = "  PgOut[async]";
+            break;
+
+    }
+    format_print(NULL, p, dio->issuing_thread, dio->type, 0, 0, 0, 7, dio->completed_time, dio->issued_time, 1, "", dio);
+}
+
+
+cache_disk_names()
+{
+    struct stat    st;
+    DIR            *dirp = NULL;
+    struct dirent  *dir;
+    struct diskrec *dnp;
+
+
+    if ((dirp = opendir("/dev")) == NULL)
+        return;
+        
+    while ((dir = readdir(dirp)) != NULL) {
+        char nbuf[MAXPATHLEN];
+        
+        if (dir->d_namlen < 5 || strncmp("disk", dir->d_name, 4))
+            continue;
+        sprintf(nbuf, "%s/%s", "/dev", dir->d_name);
+        
+	if (stat(nbuf, &st) < 0)
+            continue;
+
+        if ((dnp = (struct diskrec *)malloc(sizeof(struct diskrec))) == NULL)
+            continue;
+            
+        if ((dnp->diskname = (char *)malloc(dir->d_namlen + 1)) == NULL) {
+            free(dnp);
+            continue;
+        }
+        strncpy(dnp->diskname, dir->d_name, dir->d_namlen);
+        dnp->diskname[dir->d_namlen] = 0;
+        dnp->dev = st.st_rdev;
+        
+        dnp->next = disk_list;
+        disk_list = dnp;
+    }
+    (void) closedir(dirp);
+}
+
+
+char *find_disk_name(int dev)
+{
+    struct diskrec *dnp;
+    
+    if (dev == NFS_DEV)
+        return ("NFS");
+        
+    for (dnp = disk_list; dnp; dnp = dnp->next) {
+        if (dnp->dev == dev)
+            return (dnp->diskname);
+    }
+    return ("NOTFOUND");
+}
diff --git a/init.tproj/Makefile.postamble b/init.tproj/Makefile.postamble
index 2929636..f654506 100644
--- a/init.tproj/Makefile.postamble
+++ b/init.tproj/Makefile.postamble
@@ -2,4 +2,7 @@ INSTALL_PERMISSIONS = 500  # If set, 'install' chmod's executable to this
 #CHFLAGS = /usr/bin/chflags
 #after_install::
 #	$(CHFLAGS) schg  $(DSTROOT)$(INSTALLDIR)/$(NAME)
-
+after_install:
+	mkdir -p "$(DSTROOT)/usr/share/man/man8"
+	install -c -m 644 init.8 "$(DSTROOT)/usr/share/man/man8/init.8"
+	ln -f "$(DSTROOT)/usr/share/man/man8/init.8" "$(DSTROOT)/usr/share/man/man8/securelevel.8"
diff --git a/init.tproj/Makefile.preamble b/init.tproj/Makefile.preamble
index 3ab1a1d..04b6fe7 100644
--- a/init.tproj/Makefile.preamble
+++ b/init.tproj/Makefile.preamble
@@ -1,4 +1,4 @@
 # can be added to Compiler Flags to provide Secure login
 # -DSECURE  LIBS = -lutil   
 OTHER_GENERATED_OFILES = $(VERS_OFILE)
-
+AFTER_INSTALL = after_install
diff --git a/init.tproj/init.c b/init.tproj/init.c
index 1dd3015..b5b0979 100644
--- a/init.tproj/init.c
+++ b/init.tproj/init.c
@@ -884,7 +884,7 @@ runcom()
 		{
 		    argv[1] = _PATH_RUNCOM_BOOT;
 		    argv[2] = requested_transition == single_user
-		    	    ? "singleuser" : 0;
+		    	    ? "singleuser" : "multiuser";
 		}
 		else /* runcom_mode != BOOT_SCRIPT */
 		{
diff --git a/iostat.tproj/Makefile b/iostat.tproj/Makefile
index c18265a..e845622 100644
--- a/iostat.tproj/Makefile
+++ b/iostat.tproj/Makefile
@@ -14,8 +14,7 @@ PROJECT_TYPE = Tool
 
 CFILES = iostat.c
 
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble iostat.8\
-            names.c
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble iostat.8
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
@@ -29,6 +28,7 @@ DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
 
+FRAMEWORKS = -framework CoreFoundation -framework IOKit
 
 
 NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
diff --git a/iostat.tproj/Makefile.postamble b/iostat.tproj/Makefile.postamble
index a3733f4..e2b071c 100644
--- a/iostat.tproj/Makefile.postamble
+++ b/iostat.tproj/Makefile.postamble
@@ -85,8 +85,8 @@
 
 # Ownership and permissions of files installed by 'install' target
 #INSTALL_AS_USER = root        # User to chown app to
-INSTALL_AS_GROUP = kmem      # Group to chgrp app to 
-INSTALL_PERMISSIONS = 2555        # If set, 'install' chmod's executable to this
+#INSTALL_AS_GROUP = kmem      # Group to chgrp app to 
+#INSTALL_PERMISSIONS = 2555        # If set, 'install' chmod's executable to this
 
 # Options to strip for bundles, apps with bundles, and apps without bundles, 
 # respectively.
diff --git a/iostat.tproj/PB.project b/iostat.tproj/PB.project
index 9f8d67b..5cae2dc 100644
--- a/iostat.tproj/PB.project
+++ b/iostat.tproj/PB.project
@@ -1,11 +1,12 @@
 {
     DOCICONFILES = (); 
     FILESTABLE = {
+        FRAMEWORKS = (CoreFoundation.framework, IOKit.framework); 
         C_FILES = (); 
         H_FILES = (); 
         OTHER_LIBS = (); 
         OTHER_LINKED = (iostat.c); 
-        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, iostat.8, names.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, iostat.8); 
         PRECOMPILED_HEADERS = (); 
         PROJECT_HEADERS = (); 
         PUBLIC_HEADERS = (); 
diff --git a/iostat.tproj/iostat.8 b/iostat.tproj/iostat.8
index 48ef627..129945e 100644
--- a/iostat.tproj/iostat.8
+++ b/iostat.tproj/iostat.8
@@ -1,3 +1,32 @@
+.\"
+.\" Copyright (c) 1997 Kenneth D. Merry.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/usr.sbin/iostat/iostat.8,v 1.20 2001/08/07 13:59:48 ru Exp $
+.\"
 .\" Copyright (c) 1985, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
 .\"
@@ -31,27 +60,30 @@
 .\"
 .\"	@(#)iostat.8	8.1 (Berkeley) 6/6/93
 .\"
-.Dd June 6, 1993
+.Dd September 27, 2001
 .Dt IOSTAT 8
-.Os BSD 4
+.Os
 .Sh NAME
 .Nm iostat
 .Nd report
 .Tn I/O
 statistics
 .Sh SYNOPSIS
-.Nm iostat
+.Nm
+.Op Fl CdKIoT?\&
 .Op Fl c Ar count
-.Op Fl M Ar core
-.Op Fl N Ar system
+.Op Fl n Ar devs
 .Op Fl w Ar wait
 .Op Ar drives
 .Sh DESCRIPTION
 .Nm Iostat
 displays kernel
 .Tn I/O
-statistics on terminal, disk and cpu
-operations.
+statistics on terminal, device and cpu operations.
+The first statistics that are printed are averaged over the system uptime.
+To get information about the current activity, a suitable wait time should
+be specified, so that the subsequent sets of printed statistics will be
+averaged over that time.
 .Pp
 The options are as follows:
 .Bl -tag -width flag
@@ -59,18 +91,50 @@ The options are as follows:
 Repeat the display
 .Ar count
 times.
-The first display is for the time since a reboot and each subsequent
-report is for the time period since the last display.
 If no
 .Ar wait
 interval is specified, the default is 1 second.
-.It Fl M
-Extract values associated with the name list from the specified core
-instead of the default
-.Dq Pa /dev/kmem .
-.It Fl N
-Extract the name list from the specified system instead of the default
-.Dq Pa /vmunix .
+.It Fl C
+Display CPU statistics.
+This is on by default, unless
+.Fl d
+is specified.
+.It Fl d
+Display only device statistics.
+If this flag is turned on, only device statistics will be displayed, unless
+.Fl C
+or
+.Fl T
+is also specfied to enable the display of CPU or TTY statistics.
+.It Fl I
+Display total statstics for a given time period, rather than average
+statistics for each second during that time period.
+.It Fl K
+In the blocks transfered display (-o), display block count in kilobytes rather
+then the device native block size.
+.It Fl n
+Display up to
+.Ar devs
+number of devices.
+.Nm
+will display fewer devices if there aren't
+.Ar devs
+devices present.
+.It Fl o
+Display old-style
+.Nm
+device statistics.
+Sectors per second, transfers per second, and miliseconds per seek are
+displayed.
+If
+.Fl I
+is specified, total blocks/sectors, total transfers, and
+miliseconds per seek are displayed.
+.It Fl T
+Display TTY statistics.
+This is on by default, unless
+.Fl d
+is specified.
 .It Fl w
 Pause
 .Ar wait
@@ -78,6 +142,8 @@ seconds between each display.
 If no repeat
 .Ar count
 is specified, the default is infinity.
+.It Fl ?\&
+Display a usage statement and exit.
 .El
 .Pp
 .Nm Iostat
@@ -90,16 +156,66 @@ characters read from terminals
 .It tout
 characters written to terminals
 .El
-.It disks
-Disk operations (this field is system dependent). 
-The header of the field is the disk name and unit number.
-If more than four disk drives are configured in the system,
-.Nm iostat
-displays only the first four drives.
+.It devices
+Device operations.
+The header of the field is the device name and unit number.
+.Nm
+will display as many devices as will fit in a standard 80 column screen, or
+the maximum number of devices in the system, whichever is smaller.
+If
+.Fl n
+is specified on the command line,
+.Nm
+will display the smaller of the
+requested number of devices, and the maximum number of devices in the system.
 To force
-.Nm iostat
+.Nm
 to display specific drives, their names may be supplied on the command
 line.
+.Nm
+will not display more devices than will fit in an 80 column screen, unless
+the
+.Fl n
+argument is given on the command line to specify a maximum number of
+devices to display, or the list of specified devices exceeds 80 columns.
+If fewer devices are specified on the command line than will fit in an 80
+column screen,
+.Nm
+will show only the specified devices.
+.Pp
+The standard
+.Nm
+device display shows the following statistics:
+.Pp
+.Bl -tag -width indent -compact
+.It KB/t
+kilobytes per transfer
+.It tps
+transfers per second
+.It MB/s
+megabytes per second
+.El
+.Pp
+The standard
+.Nm
+device display, with the
+.Fl I
+flag specified, shows the following statistics:
+.Pp
+.Bl -tag -width indent -compact
+.It KB/t
+kilobytes per transfer
+.It xfrs
+total number of transfers
+.It MB
+total number of megabytes transferred
+.El
+.Pp
+The old-style
+.Nm
+display (using
+.Fl o )
+shows the following statistics:
 .Pp
 .Bl -tag -width indent -compact
 .It sps
@@ -107,36 +223,70 @@ sectors transferred per second
 .It tps
 transfers per second
 .It msps
-milliseconds per average seek (including implied
-seeks and rotational latency)
+average milliseconds per transaction
+.El
+.Pp
+The old-style
+.Nm
+display, with the
+.Fl I
+flag specified, shows the following statistics:
+.Pp
+.Bl -tag -width indent -compact
+.It blk
+total blocks/sectors transferred
+.It xfr
+total transfers
+.It msps
+average milliseconds per transaction
 .El
 .It cpu
 .Bl -tag -width indent -compact
 .It \&us
 % of cpu time in user mode
-.It \&ni
-% of cpu time in user mode running niced processes
 .It \&sy
 % of cpu time in system mode
 .It \&id
 % of cpu time in idle mode
 .El
 .El
-.Sh FILES
-.Bl -tag -width /dev/kmem -compact
-.It Pa /vmunix
-Default kernel namelist.
-.It Pa /dev/kmem
-Default memory file.
-.El
+.Sh EXAMPLES
+.Dl iostat -w 1 disk0 disk2
+.Pp
+Display statistics for the first and third disk devices device every
+second ad infinitum.
+.Pp
+.Dl iostat -c 2
+.Pp
+Display the statistics for the first four devices in the system twice, with
+a one second display interval.
+.Pp
+.Dl iostat -Iw 3
+.Pp
+Display total statistics every three seconds ad infinitum.
+.Pp
+.Dl iostat -odICTw 2 -c 9
+.Pp
+Display total statistics using the old-style output format 9 times, with
+a two second interval between each measurement/display.
+The
+.Fl d
+flag generally disables the TTY and CPU displays, but since the
+.Fl T
+and
+.Fl C
+flags are given, the TTY and CPU displays will be displayed.
 .Sh SEE ALSO
 .Xr fstat 1 ,
 .Xr netstat 1 ,
 .Xr nfsstat 1 ,
-.Xr \&ps 1 ,
-.Xr systat 1 ,
-.Xr vmstat 1 ,
-.Xr pstat 8
+.Xr ps 1 ,
+.Xr pstat 8 ,
 .Pp
 The sections starting with ``Interpreting system activity'' in
 .%T "Installing and Operating 4.3BSD" .
+.Sh HISTORY
+This version of
+.Nm
+first appeared in
+.Nm FreeBSD 3.0 .
diff --git a/iostat.tproj/iostat.c b/iostat.tproj/iostat.c
index 54cbf1c..da5fe41 100644
--- a/iostat.tproj/iostat.c
+++ b/iostat.tproj/iostat.c
@@ -21,6 +21,39 @@
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
+/*
+ * Copyright (c) 1997, 1998, 2000, 2001  Kenneth D. Merry
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/usr.sbin/iostat/iostat.c,v 1.22 2001/09/01 07:40:19 kris Exp $
+ */
+/*
+ * Parts of this program are derived from the original FreeBSD iostat
+ * program:
+ */
 /*-
  * Copyright (c) 1986, 1991, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -53,362 +86,800 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+/*
+ * Ideas for the new iostat statistics output modes taken from the NetBSD
+ * version of iostat:
+ */
+/*
+ * Copyright (c) 1996 John M. Vinopal
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed for the NetBSD Project
+ *      by John M. Vinopal.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
-#ifndef lint
-static char copyright[] =
-"@(#) Copyright (c) 1986, 1991, 1993\n\
-	The Regents of the University of California.  All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char sccsid[] = "@(#)iostat.c	8.3 (Berkeley) 4/28/95";
-#endif /* not lint */
+#define IOKIT	1	/* to get io_name_t in device_types.h */
 
 #include <sys/param.h>
-#include <sys/buf.h>
-#include <sys/dkstat.h>
+#include <sys/sysctl.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/storage/IOBlockStorageDriver.h>
+#include <IOKit/storage/IOMedia.h>
+#include <IOKit/IOBSD.h>
 
 #include <err.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <kvm.h>
-#include <limits.h>
-#include <nlist.h>
-#include <paths.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-struct nlist namelist[] = {
-#define	X_DK_TIME	0
-	{ "_dk_time" },
-#define	X_DK_XFER	1
-	{ "_dk_xfer" },
-#define	X_DK_WDS	2
-	{ "_dk_wds" },
-#define	X_TK_NIN	3
-	{ "_tk_nin" },
-#define	X_TK_NOUT	4
-	{ "_tk_nout" },
-#define	X_DK_SEEK	5
-	{ "_dk_seek" },
-#define	X_CP_TIME	6
-	{ "_cp_time" },
-#define	X_DK_WPMS	7
-	{ "_dk_wpms" },
-#define	X_HZ		8
-	{ "_hz" },
-#define	X_STATHZ	9
-	{ "_stathz" },
-#define	X_DK_NDRIVE	10
-	{ "_dk_ndrive" },
-#define	X_END		10
-#if defined(hp300) || defined(luna68k)
-#define	X_HPDINIT	(X_END+1)
-	{ "_hp_dinit" },
-#endif
-#ifdef mips
-#define	X_SCSI_DINIT	(X_END+1)
-	{ "_scsi_dinit" },
-#endif
-#ifdef tahoe
-#define	X_VBDINIT	(X_END+1)
-	{ "_vbdinit" },
-#endif
-#ifdef vax
-	{ "_mbdinit" },
-#define X_MBDINIT	(X_END+1)
-	{ "_ubdinit" },
-#define X_UBDINIT	(X_END+2)
-#endif
-	{ NULL },
+#define MAXDRIVES	16	/* most drives we will record */
+#define MAXDRIVENAME	31	/* largest drive name we allow */
+
+struct drivestats {
+	io_registry_entry_t	driver;
+	char			name[MAXDRIVENAME + 1];
+	u_int64_t		blocksize;
+	u_int64_t		total_bytes;
+	u_int64_t		total_transfers;
+	u_int64_t		total_time;
 };
 
-struct _disk {
-	long	cp_time[CPUSTATES];
-	long	*dk_time;
-	long	*dk_wds;
-	long	*dk_seek;
-	long	*dk_xfer;
-	long	tk_nin;
-	long	tk_nout;
-} cur, last;
+static struct drivestats drivestat[MAXDRIVES];
+
+static struct timeval	cur_time, last_time;
+
+struct statinfo {
+	long		tk_nin;
+	long		tk_nout;
+	host_cpu_load_info_data_t load;
+};
+
+static struct statinfo cur, last;
+
+static mach_port_t host_priv_port;
+static mach_port_t masterPort;
+
+static int num_devices;
+static int maxshowdevs;
+static int dflag = 0, Iflag = 0, Cflag = 0, Tflag = 0, oflag = 0, Kflag = 0;
+static volatile sig_atomic_t phdr_flag = 0;
 
-kvm_t	 *kd;
-double	  etime;
-long	 *dk_wpms;
-int	  dk_ndrive, *dr_select, hz, kmemfd, ndrives;
-char	**dr_name;
+/* local function declarations */
+static void usage(void);
+static void phdr(int signo);
+static void do_phdr();
+static void devstats(int perf_select, long double etime, int havelast);
+static void cpustats(void);
+static int readvar(const char *name, void *ptr, size_t len);
 
-#define nlread(x, v) \
-	kvm_read(kd, namelist[x].n_value, &(v), sizeof(v))
+static int record_all_devices(void);
+static int record_one_device(char *name);
+static int record_device(io_registry_entry_t drive);
 
-#include "names.c"				/* XXX */
+static long double compute_etime(struct timeval cur_time, 
+				 struct timeval prev_time);
 
-void cpustats __P((void));
-void dkstats __P((void));
-void phdr __P((int));
-void usage __P((void));
+static void
+usage(void)
+{
+	/*
+	 * We also support the following 'traditional' syntax:
+	 * iostat [drives] [wait [count]]
+	 * This isn't mentioned in the man page, or the usage statement,
+	 * but it is supported.
+	 */
+	fprintf(stderr, "usage: iostat [-CdIKoT?] [-c count] [-n devs]\n"
+		"\t      [-w wait] [drives]\n");
+}
 
 int
-main(argc, argv)
-	int argc;
-	char *argv[];
+main(int argc, char **argv)
 {
-	register int i;
-	long tmp;
-	int ch, hdrcnt, reps, interval, stathz, ndrives;
-	char **cp, *memf, *nlistf, buf[30];
-        char errbuf[_POSIX2_LINE_MAX];
-
-	interval = reps = 0;
-	nlistf = memf = NULL;
-	while ((ch = getopt(argc, argv, "c:M:N:w:")) != EOF)
-		switch(ch) {
-		case 'c':
-			if ((reps = atoi(optarg)) <= 0)
-				errx(1, "repetition count <= 0.");
-			break;
-		case 'M':
-			memf = optarg;
-			break;
-		case 'N':
-			nlistf = optarg;
-			break;
-		case 'w':
-			if ((interval = atoi(optarg)) <= 0)
-				errx(1, "interval <= 0.");
-			break;
-		case '?':
-		default:
-			usage();
+	int c;
+	int hflag = 0, cflag = 0, wflag = 0, nflag = 0;
+	int count = 0, waittime = 0;
+	int headercount;
+	int num_devices_specified;
+	int havelast = 0;
+
+	maxshowdevs = 3;
+
+	while ((c = getopt(argc, argv, "c:CdIKM:n:oTw:?")) != -1) {
+		switch(c) {
+			case 'c':
+				cflag++;
+				count = atoi(optarg);
+				if (count < 1)
+					errx(1, "count %d is < 1", count);
+				break;
+			case 'C':
+				Cflag++;
+				break;
+			case 'd':
+				dflag++;
+				break;
+			case 'I':
+				Iflag++;
+				break;
+			case 'K':
+				Kflag++;
+				break;
+			case 'n':
+				nflag++;
+				maxshowdevs = atoi(optarg);
+				if (maxshowdevs < 0)
+					errx(1, "number of devices %d is < 0",
+					     maxshowdevs);
+				break;
+			case 'o':
+				oflag++;
+				break;
+			case 'T':
+				Tflag++;
+				break;
+			case 'w':
+				wflag++;
+				waittime = atoi(optarg);
+				if (waittime < 1)
+					errx(1, "wait time is < 1");
+				break;
+			default:
+				usage();
+				exit(1);
+				break;
 		}
+	}
+
 	argc -= optind;
 	argv += optind;
 
 	/*
-	 * Discard setgid privileges if not the running kernel so that bad
-	 * guys can't print interesting stuff from kernel memory.
+	 * Get the Mach private port.
+	 */
+	host_priv_port = mach_host_self();
+
+	/*
+	 * Get the I/O Kit communication handle.
+	 */
+	IOMasterPort(bootstrap_port, &masterPort);
+
+	/*
+	 * Make sure Tflag and/or Cflag are set if dflag == 0.  If dflag is
+	 * greater than 0, they may be 0 or non-zero.
 	 */
-	if (nlistf != NULL || memf != NULL)
-		setgid(getgid());
-
-        kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
-	if (kd == 0)
-		errx(1, "kvm_openfiles: %s", errbuf);
-	if (kvm_nlist(kd, namelist) == -1)
-		errx(1, "kvm_nlist: %s", kvm_geterr(kd));
-	if (namelist[X_DK_NDRIVE].n_type == 0)
-		errx(1, "dk_ndrive not found in namelist");
-	(void)nlread(X_DK_NDRIVE, dk_ndrive);
-	if (dk_ndrive <= 0)
-		errx(1, "invalid dk_ndrive %d\n", dk_ndrive);
-
-	cur.dk_time = calloc(dk_ndrive, sizeof(long));
-	cur.dk_wds = calloc(dk_ndrive, sizeof(long));
-	cur.dk_seek = calloc(dk_ndrive, sizeof(long));
-	cur.dk_xfer = calloc(dk_ndrive, sizeof(long));
-	last.dk_time = calloc(dk_ndrive, sizeof(long));
-	last.dk_wds = calloc(dk_ndrive, sizeof(long));
-	last.dk_seek = calloc(dk_ndrive, sizeof(long));
-	last.dk_xfer = calloc(dk_ndrive, sizeof(long));
-	dr_select = calloc(dk_ndrive, sizeof(int));
-	dr_name = calloc(dk_ndrive, sizeof(char *));
-	dk_wpms = calloc(dk_ndrive, sizeof(long));
-
-	for (i = 0; i < dk_ndrive; i++) {
-		(void)sprintf(buf, "dk%d", i);
-		dr_name[i] = strdup(buf);
+	if (dflag == 0) {
+		Cflag = 1;
+		Tflag = 1;
 	}
-	if (!read_names())
-		exit(1);
-	(void)nlread(X_HZ, hz);
-	(void)nlread(X_STATHZ, stathz);
-	if (stathz)
-		hz = stathz;
-	(void)kvm_read(kd, namelist[X_DK_WPMS].n_value, dk_wpms,
-		dk_ndrive * sizeof(dk_wpms));
 
 	/*
-	 * Choose drives to be displayed.  Priority goes to (in order) drives
-	 * supplied as arguments and default drives.  If everything isn't
-	 * filled in and there are drives not taken care of, display the first
-	 * few that fit.
-	 *
-	 * The backward compatibility #ifdefs permit the syntax:
-	 *	iostat [ drives ] [ interval [ count ] ]
+	 * Figure out how many devices we should display if not given
+	 * an explicit value.
+	 */
+	if (nflag == 0) {
+		if (oflag > 0) {
+			if ((dflag > 0) && (Cflag == 0) && (Tflag == 0))
+				maxshowdevs = 5;
+			else if ((dflag > 0) && (Tflag > 0) && (Cflag == 0))
+				maxshowdevs = 5;
+			else
+				maxshowdevs = 4;
+		} else {
+			if ((dflag > 0) && (Cflag == 0))
+				maxshowdevs = 4;		
+			else
+				maxshowdevs = 3;
+		}
+	}
+
+	/*
+	 * If the user specified any devices on the command line, record
+	 * them for monitoring.
 	 */
-#define	BACKWARD_COMPATIBILITY
-	for (ndrives = 0; *argv; ++argv) {
-#ifdef	BACKWARD_COMPATIBILITY
+	for (num_devices_specified = 0; *argv; ++argv) {
 		if (isdigit(**argv))
 			break;
-#endif
-		for (i = 0; i < dk_ndrive; i++) {
-			if (strcmp(dr_name[i], *argv))
-				continue;
-			dr_select[i] = 1;
-			++ndrives;
-		}
+		if (record_one_device(*argv))
+			errx(1, "can't record '%s' for monitoring");
+		num_devices_specified++;
 	}
-#ifdef	BACKWARD_COMPATIBILITY
+	if (nflag == 0 && maxshowdevs < num_devices_specified)
+		maxshowdevs = num_devices_specified;
+
+	/* if no devices were specified, pick them ourselves */
+	if ((num_devices_specified == 0) && record_all_devices())
+		err(1, "can't find any devices to display");
+
+	/*
+	 * Look for the traditional wait time and count arguments.
+	 */
 	if (*argv) {
-		interval = atoi(*argv);
-		if (*++argv)
-			reps = atoi(*argv);
-	}
-#endif
-
-	if (interval) {
-		if (!reps)
-			reps = -1;
-	} else
-		if (reps)
-			interval = 1;
-
-	for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
-		if (dr_select[i] || dk_wpms[i] == 0)
-			continue;
-		for (cp = defdrives; *cp; cp++)
-			if (strcmp(dr_name[i], *cp) == 0) {
-				dr_select[i] = 1;
-				++ndrives;
-				break;
-			}
-	}
-	for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
-		if (dr_select[i])
-			continue;
-		dr_select[i] = 1;
-		++ndrives;
+		waittime = atoi(*argv);
+
+		/* Let the user know he goofed, but keep going anyway */
+		if (wflag != 0) 
+			warnx("discarding previous wait interval, using"
+			      " %d instead", waittime);
+		wflag++;
+
+		if (*++argv) {
+			count = atoi(*argv);
+			if (cflag != 0)
+				warnx("discarding previous count, using %d"
+				      " instead", count);
+			cflag++;
+		} else
+			count = -1;
 	}
 
+	/*
+	 * If the user specified a count, but not an interval, we default
+	 * to an interval of 1 second.
+	 */
+	if ((wflag == 0) && (cflag > 0))
+		waittime = 1;
+
+	/*
+	 * If the user specified a wait time, but not a count, we want to
+	 * go on ad infinitum.  This can be redundant if the user uses the
+	 * traditional method of specifying the wait, since in that case we
+	 * already set count = -1 above.  Oh well.
+	 */
+	if ((wflag > 0) && (cflag == 0))
+		count = -1;
+
+	cur.tk_nout = 0;
+	cur.tk_nin = 0;
+
+	/*
+	 * Set the busy time to the system boot time, so the stats are
+	 * calculated since system boot.
+	 */
+	if (readvar("kern.boottime", &cur_time,	sizeof(cur_time)) != 0)
+		exit(1);
+
+	/*
+	 * If the user stops the program (control-Z) and then resumes it,
+	 * print out the header again.
+	 */
 	(void)signal(SIGCONT, phdr);
 
-	for (hdrcnt = 1;;) {
-		if (!--hdrcnt) {
-			phdr(0);
-			hdrcnt = 20;
+	for (headercount = 1;;) {
+		long tmp;
+		long double etime;
+
+		if (Tflag > 0) {
+			if ((readvar("kern.tty_nin", &cur.tk_nin,
+			     sizeof(cur.tk_nin)) != 0)
+			 || (readvar("kern.tty_nout",
+			     &cur.tk_nout, sizeof(cur.tk_nout))!= 0)) {
+				Tflag = 0;
+				warnx("disabling TTY statistics");
+			}
+		 }
+
+		if (phdr_flag) {
+			phdr_flag = 0;
+			do_phdr();
 		}
-		(void)kvm_read(kd, namelist[X_DK_TIME].n_value,
-		    cur.dk_time, dk_ndrive * sizeof(long));
-		(void)kvm_read(kd, namelist[X_DK_XFER].n_value,
-		    cur.dk_xfer, dk_ndrive * sizeof(long));
-		(void)kvm_read(kd, namelist[X_DK_WDS].n_value,
-		    cur.dk_wds, dk_ndrive * sizeof(long));
-		(void)kvm_read(kd, namelist[X_DK_SEEK].n_value,
-		    cur.dk_seek, dk_ndrive * sizeof(long));
-		(void)kvm_read(kd, namelist[X_TK_NIN].n_value,
-		    &cur.tk_nin, sizeof(cur.tk_nin));
-		(void)kvm_read(kd, namelist[X_TK_NOUT].n_value,
-		    &cur.tk_nout, sizeof(cur.tk_nout));
-		(void)kvm_read(kd, namelist[X_CP_TIME].n_value,
-		    cur.cp_time, sizeof(cur.cp_time));
-		for (i = 0; i < dk_ndrive; i++) {
-			if (!dr_select[i])
-				continue;
-#define X(fld)	tmp = cur.fld[i]; cur.fld[i] -= last.fld[i]; last.fld[i] = tmp
-			X(dk_xfer);
-			X(dk_seek);
-			X(dk_wds);
-			X(dk_time);
+		
+		if (!--headercount) {
+			do_phdr();
+			headercount = 20;
 		}
-		tmp = cur.tk_nin;
-		cur.tk_nin -= last.tk_nin;
-		last.tk_nin = tmp;
-		tmp = cur.tk_nout;
-		cur.tk_nout -= last.tk_nout;
-		last.tk_nout = tmp;
-		etime = 0;
-		for (i = 0; i < CPUSTATES; i++) {
-			X(cp_time);
-			etime += cur.cp_time[i];
+
+		last_time = cur_time;
+		gettimeofday(&cur_time, NULL);
+
+		if (Tflag > 0) {
+			tmp = cur.tk_nin;
+			cur.tk_nin -= last.tk_nin;
+			last.tk_nin = tmp;
+			tmp = cur.tk_nout;
+			cur.tk_nout -= last.tk_nout;
+			last.tk_nout = tmp;
 		}
+
+		etime = compute_etime(cur_time, last_time);
+
 		if (etime == 0.0)
 			etime = 1.0;
-		etime /= (float)hz;
-		(void)printf("%4.0f%5.0f",
-		    cur.tk_nin / etime, cur.tk_nout / etime);
-		dkstats();
-		cpustats();
-		(void)printf("\n");
-		(void)fflush(stdout);
 
-		if (reps >= 0 && --reps <= 0)
+		if (Tflag > 0)
+			printf("%4.0Lf%5.0Lf", cur.tk_nin / etime, 
+				cur.tk_nout / etime);
+
+		devstats(hflag, etime, havelast);
+
+		if (Cflag > 0)
+			cpustats();
+
+		printf("\n");
+		fflush(stdout);
+
+		if (count >= 0 && --count <= 0)
 			break;
-		(void)sleep(interval);
+
+		sleep(waittime);
+		havelast = 1;
 	}
+
 	exit(0);
 }
 
-/* ARGUSED */
-void
-phdr(signo)
-	int signo;
+static void
+phdr(int signo)
+{
+
+	phdr_flag = 1;	
+}
+
+static void
+do_phdr() 
 {
 	register int i;
 
-	(void)printf("      tty");
-	for (i = 0; i < dk_ndrive; i++)
-		if (dr_select[i])
-			(void)printf("          %3.3s ", dr_name[i]);
-	(void)printf("         cpu\n tin tout");
-	for (i = 0; i < dk_ndrive; i++)
-		if (dr_select[i])
-			(void)printf(" sps tps msps ");
-	(void)printf(" us ni sy in id\n");
+	if (Tflag > 0)
+		(void)printf("      tty");
+
+	for (i = 0; (i < num_devices); i++){
+		if (oflag > 0)
+			(void)printf("%12.6s ", drivestat[i].name);
+		else
+			printf("%15.6s ", drivestat[i].name);
+	}
+		
+	if (Cflag > 0)
+		(void)printf("      cpu\n");
+	else
+		(void)printf("\n");
+
+	if (Tflag > 0)
+		(void)printf(" tin tout");
+
+	for (i=0; i < num_devices; i++){
+		if (oflag > 0) {
+			if (Iflag == 0)
+				(void)printf(" sps tps msps ");
+			else
+				(void)printf(" blk xfr msps ");
+		} else {
+			if (Iflag == 0)
+				printf("  KB/t tps  MB/s ");
+			else
+				printf("  KB/t xfrs   MB ");
+		}
+	}
+
+	if (Cflag > 0)
+		(void)printf(" us sy id\n");
+	else
+		printf("\n");
 }
 
-void
-dkstats()
+static void
+devstats(int perf_select, long double etime, int havelast)
 {
-	register int dn;
-	double atime, itime, msps, words, xtime;
-
-	for (dn = 0; dn < dk_ndrive; ++dn) {
-		if (!dr_select[dn])
-			continue;
-		words = cur.dk_wds[dn] * 32;		/* words xfer'd */
-		(void)printf("%4.0f",			/* sectors */
-		    words / (DEV_BSIZE / 2) / etime);
-
-		(void)printf("%4.0f", cur.dk_xfer[dn] / etime);
-
-		if (dk_wpms[dn] && cur.dk_xfer[dn]) {
-			atime = cur.dk_time[dn];	/* ticks disk busy */
-			atime /= (float)hz;		/* ticks to seconds */
-			xtime = words / dk_wpms[dn];	/* transfer time */
-			itime = atime - xtime;		/* time not xfer'ing */
-			if (itime < 0)
-				msps = 0;
+	CFNumberRef number;
+	CFDictionaryRef properties;
+	CFDictionaryRef statistics;
+	long double transfers_per_second;
+	long double kb_per_transfer, mb_per_second;
+	u_int64_t value;
+	u_int64_t total_bytes, total_transfers, total_blocks, total_time;
+	u_int64_t interval_bytes, interval_transfers, interval_blocks;
+	u_int64_t interval_time;
+	long double interval_mb;
+	long double blocks_per_second, ms_per_transaction;
+	kern_return_t status;
+	int i;
+
+	for (i = 0; i < num_devices; i++) {
+
+		/*
+		 * If the drive goes away, we may not get any properties
+		 * for it.  So take some defaults.
+		 */
+		total_bytes = 0;
+		total_transfers = 0;
+		total_time = 0;
+
+		/* get drive properties */
+		status = IORegistryEntryCreateCFProperties(drivestat[i].driver,
+			(CFMutableDictionaryRef *)&properties,
+			kCFAllocatorDefault,
+			kNilOptions);
+		if (status != KERN_SUCCESS)
+			err(1, "device has no properties");
+
+		/* get statistics from properties */
+		statistics = (CFDictionaryRef)CFDictionaryGetValue(properties,
+			CFSTR(kIOBlockStorageDriverStatisticsKey));
+		if (statistics) {
+
+			/*
+			 * Get I/O volume.
+			 */
+			if ((number = (CFNumberRef)CFDictionaryGetValue(statistics,
+				CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)))) {
+				CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+				total_bytes += value;
+			}
+			if ((number = (CFNumberRef)CFDictionaryGetValue(statistics,
+				CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)))) {
+				CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+				total_bytes += value;
+			}
+
+			/*
+			 * Get I/O counts.
+			 */
+			if ((number = (CFNumberRef)CFDictionaryGetValue(statistics,
+				CFSTR(kIOBlockStorageDriverStatisticsReadsKey)))) {
+				CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+				total_transfers += value;
+			}
+			if ((number = (CFNumberRef)CFDictionaryGetValue(statistics,
+				CFSTR(kIOBlockStorageDriverStatisticsWritesKey)))) {
+				CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+				total_transfers += value;
+			}
+
+			/*
+			 * Get I/O time.
+			 */
+			if ((number = (CFNumberRef)CFDictionaryGetValue(statistics,
+				CFSTR(kIOBlockStorageDriverStatisticsLatentReadTimeKey)))) {
+				CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+				total_time += value;
+			}
+			if ((number = (CFNumberRef)CFDictionaryGetValue(statistics,
+				CFSTR(kIOBlockStorageDriverStatisticsLatentWriteTimeKey)))) {
+				CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+				total_time += value;
+			}
+
+		}
+		CFRelease(properties);
+
+		/*
+		 * Compute delta values and stats.
+		 */
+		interval_bytes = total_bytes - drivestat[i].total_bytes;
+		interval_transfers = total_transfers 
+			- drivestat[i].total_transfers;
+		interval_time = total_time - drivestat[i].total_time;
+
+		/* update running totals, only once for -I */
+		if ((Iflag == 0) || (drivestat[i].total_bytes == 0)) {
+			drivestat[i].total_bytes = total_bytes;
+			drivestat[i].total_transfers = total_transfers;
+			drivestat[i].total_time = total_time;
+		}				
+
+		interval_blocks = interval_bytes / drivestat[i].blocksize;
+		total_blocks = total_bytes / drivestat[i].blocksize;
+
+		blocks_per_second = interval_blocks / etime;
+		transfers_per_second = interval_transfers / etime;
+		mb_per_second = (interval_bytes / etime) / (1024 * 1024);
+
+		kb_per_transfer = (interval_transfers > 0) ?
+			((long double)interval_bytes / interval_transfers) 
+			/ 1024 : 0;
+
+		/* times are in nanoseconds, convert to milliseconds */
+		ms_per_transaction = (interval_transfers > 0) ?
+			((long double)interval_time / interval_transfers) 
+			/ 1000 : 0;
+
+		if (Kflag)
+			total_blocks = total_blocks * drivestat[i].blocksize 
+				/ 1024;
+
+		if (oflag > 0) {
+			int msdig = (ms_per_transaction < 100.0) ? 1 : 0;
+
+			if (Iflag == 0)
+				printf("%4.0Lf%4.0Lf%5.*Lf ",
+				       blocks_per_second,
+				       transfers_per_second,
+				       msdig,
+				       ms_per_transaction);
 			else 
-				msps = itime * 1000 / cur.dk_xfer[dn];
-		} else
-			msps = 0;
-		(void)printf("%5.1f ", msps);
+				printf("%4.1qu%4.1qu%5.*Lf ",
+				       interval_blocks,
+				       interval_transfers,
+				       msdig,
+				       ms_per_transaction);
+		} else {
+			if (Iflag == 0)
+				printf(" %5.2Lf %3.0Lf %5.2Lf ", 
+				       kb_per_transfer,
+				       transfers_per_second,
+				       mb_per_second);
+			else {
+				interval_mb = interval_bytes;
+				interval_mb /= 1024 * 1024;
+
+				printf(" %5.2Lf %3.1qu %5.2Lf ", 
+				       kb_per_transfer,
+				       interval_transfers,
+				       interval_mb);
+			}
+		}
 	}
 }
 
-void
-cpustats()
+static void
+cpustats(void)
 {
-	register int state;
+	mach_msg_type_number_t count;
+	kern_return_t status;
 	double time;
 
-	time = 0;
-	for (state = 0; state < CPUSTATES; ++state)
-		time += cur.cp_time[state];
-	for (state = 0; state < CPUSTATES; ++state)
-		(void)printf("%3.0f",
-		    100. * cur.cp_time[state] / (time ? time : 1));
+	/*
+	 * Get CPU usage counters.
+	 */
+	count = HOST_CPU_LOAD_INFO_COUNT;
+	status = host_statistics(host_priv_port, HOST_CPU_LOAD_INFO,
+		(host_info_t)&cur.load, &count);
+	if (status != KERN_SUCCESS)
+		errx(1, "couldn't fetch CPU stats");
+
+	/*
+	 * Make 'cur' fields relative, update 'last' fields to current values,
+	 * calculate total elapsed time.
+	 */
+	time = 0.0;
+	cur.load.cpu_ticks[CPU_STATE_USER]
+		-= last.load.cpu_ticks[CPU_STATE_USER];
+	last.load.cpu_ticks[CPU_STATE_USER]
+		+= cur.load.cpu_ticks[CPU_STATE_USER];
+	time += cur.load.cpu_ticks[CPU_STATE_USER];
+	cur.load.cpu_ticks[CPU_STATE_SYSTEM]
+		-= last.load.cpu_ticks[CPU_STATE_SYSTEM];
+	last.load.cpu_ticks[CPU_STATE_SYSTEM]
+		+= cur.load.cpu_ticks[CPU_STATE_SYSTEM];
+	time += cur.load.cpu_ticks[CPU_STATE_SYSTEM];
+	cur.load.cpu_ticks[CPU_STATE_IDLE]
+		-= last.load.cpu_ticks[CPU_STATE_IDLE];
+	last.load.cpu_ticks[CPU_STATE_IDLE]
+		+= cur.load.cpu_ticks[CPU_STATE_IDLE];
+	time += cur.load.cpu_ticks[CPU_STATE_IDLE];
+	
+	/*
+	 * Print times.
+	 */
+	printf("%3.0f",
+		rint(100. * cur.load.cpu_ticks[CPU_STATE_USER]
+		     / (time ? time : 1)));
+	printf("%3.0f",
+		rint(100. * cur.load.cpu_ticks[CPU_STATE_SYSTEM]
+		     / (time ? time : 1)));
+	printf("%3.0f",
+		rint(100. * cur.load.cpu_ticks[CPU_STATE_IDLE]
+		     / (time ? time : 1)));
+}
+
+static int
+readvar(const char *name, void *ptr, size_t len)
+{
+	int	oid[4];
+	int	oidlen;
+
+	size_t nlen = len;
+
+	if (sysctlbyname(name, ptr, &nlen, NULL, 0) == -1) {
+		if (errno != ENOENT) {
+			warn("sysctl(%s) failed", name);
+			return (1);
+		}
+		/*
+		 * XXX fallback code to deal with systems where
+		 * sysctlbyname can't find "old" OIDs, should be removed.
+		 */
+		if (!strcmp(name, "kern.boottime")) {
+			oid[0] = CTL_KERN;
+			oid[1] = KERN_BOOTTIME;
+			oidlen = 2;
+		} else {
+			warn("sysctl(%s) failed", name);
+			return (1);
+		}
+
+		nlen = len;
+		if (sysctl(oid, oidlen, ptr, &nlen, NULL, 0) == -1) {
+			warn("sysctl(%s) failed", name);
+			return (1);
+		}
+	}
+	if (nlen != len) {
+		warnx("sysctl(%s): expected %lu, got %lu", name,
+		      (unsigned long)len, (unsigned long)nlen);
+		return (1);
+	}
+	return (0);
 }
 
-void
-usage()
+static long double
+compute_etime(struct timeval cur_time, struct timeval prev_time)
 {
-	(void)fprintf(stderr,
-"usage: iostat [-c count] [-M core] [-N system] [-w wait] [drives]\n");
-	exit(1);
+	struct timeval busy_time;
+	u_int64_t busy_usec;
+	long double etime;
+
+	timersub(&cur_time, &prev_time, &busy_time);
+
+	busy_usec = busy_time.tv_sec;  
+	busy_usec *= 1000000;          
+	busy_usec += busy_time.tv_usec;
+	etime = busy_usec;
+	etime /= 1000000;
+
+	return(etime);
+}
+
+/*
+ * Record all "whole" IOMedia objects as being interesting.
+ */
+static int
+record_all_devices(void)
+{
+	io_iterator_t drivelist;
+	io_registry_entry_t drive;
+	CFMutableDictionaryRef match;
+	int error, ndrives;
+	kern_return_t status;
+
+	/*
+	 * Get an iterator for IOMedia objects.
+	 */
+	match = IOServiceMatching("IOMedia");
+	CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue);
+	status = IOServiceGetMatchingServices(masterPort, match, &drivelist);
+	if (status != KERN_SUCCESS)
+		errx(1, "couldn't match whole IOMedia devices");
+
+	/*
+	 * Scan all of the IOMedia objects, and for each
+	 * object that has a parent IOBlockStorageDriver, save
+	 * the object's name and the parent (from which we can
+	 * fetch statistics).
+	 *
+	 * XXX What about RAID devices?
+	 */
+	error = 1;
+	ndrives = 0;
+	while ((drive = IOIteratorNext(drivelist))
+		&& (ndrives < maxshowdevs)) {
+		if (!record_device(drive)) {
+			error = 0;
+			ndrives++;
+		}
+		IOObjectRelease(drive);
+	}
+	IOObjectRelease(drivelist);
+
+	return(error);
+}
+
+/*
+ * Try to record the named device as interesting.  It
+ * must be an IOMedia device.
+ */
+static int
+record_one_device(char *name)
+{
+	io_iterator_t drivelist;
+	io_registry_entry_t drive;
+	kern_return_t status;
+
+	/*
+	 * Find the device.
+	 */
+	status = IOServiceGetMatchingServices(masterPort,
+		IOBSDNameMatching(masterPort, kNilOptions, name),
+		&drivelist);
+	if (status != KERN_SUCCESS)
+		errx(1, "couldn't match '%s'", name);
+
+	/*
+	 * Get the first match (should only be one)
+	 */
+	if ((drive = IOIteratorNext(drivelist)) == NULL)
+		errx(1, "'%s' not found", name);
+	if (!IOObjectConformsTo(drive, "IOMedia"))
+		errx(1, "'%s' is not a storage device", name);
+
+	/*
+	 * Record the device.
+	 */
+	if (record_device(drive))
+		errx(1, "could not record '%s' for monitoring", name);
+
+	IOObjectRelease(drive);
+	IOObjectRelease(drivelist);
+
+	return(0);
+}
+
+/*
+ * Determine whether an IORegistryEntry refers to a valid
+ * I/O device, and if so, record it.
+ */
+static int
+record_device(io_registry_entry_t drive)
+{
+	io_registry_entry_t parent;
+	CFDictionaryRef properties;
+	CFStringRef name;
+	CFNumberRef number;
+	kern_return_t status;
+	
+	/* get drive's parent */
+	status = IORegistryEntryGetParentEntry(drive,
+		kIOServicePlane, &parent);
+	if (status != KERN_SUCCESS)
+		errx(1, "device has no parent");
+	if (IOObjectConformsTo(parent, "IOBlockStorageDriver")) {
+		drivestat[num_devices].driver = parent;
+
+		/* get drive properties */
+		status = IORegistryEntryCreateCFProperties(drive,
+			(CFMutableDictionaryRef *)&properties,
+			kCFAllocatorDefault,
+			kNilOptions);
+		if (status != KERN_SUCCESS)
+			errx(1, "device has no properties");
+
+		/* get name from properties */
+		name = (CFStringRef)CFDictionaryGetValue(properties,
+			CFSTR(kIOBSDNameKey));
+		CFStringGetCString(name, drivestat[num_devices].name, 
+			MAXDRIVENAME, CFStringGetSystemEncoding());
+
+		/* get blocksize from properties */
+		number = (CFNumberRef)CFDictionaryGetValue(properties,
+			CFSTR(kIOMediaPreferredBlockSizeKey));
+		CFNumberGetValue(number, kCFNumberSInt64Type,
+			&drivestat[num_devices].blocksize);
+
+		/* clean up, return success */
+		CFRelease(properties);
+		num_devices++;
+		return(0);
+	}
+
+	/* failed, don't keep parent */
+	IOObjectRelease(parent);
+	return(1);
 }
diff --git a/iostat.tproj/names.c b/iostat.tproj/names.c
deleted file mode 100644
index 099ea61..0000000
--- a/iostat.tproj/names.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1986, 1991, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if !defined(hp300) && !defined(tahoe) && !defined(vax) && \
-	!defined(luna68k) && !defined(mips)
-char *defdrives[] = { 0 };
-int
-read_names()
-{
-    return 0;
-}
-#endif
-
-#if defined(hp300) || defined(luna68k)
-#if defined(hp300)
-#include <hp/dev/device.h>
-#else
-#include <luna68k/dev/device.h>
-#endif
-
-char *defdrives[] = { "sd0", "sd1", "sd2", "rd0", "rd1", "rd2", 0 };
-
-int
-read_names()
-{
-	register char *p;
-	register u_long hp;
-	static char buf[BUFSIZ];
-	struct hp_device hdev;
-	struct driver hdrv;
-	char name[10];
-
-	hp = namelist[X_HPDINIT].n_value;
-	if (hp == 0) {
-		(void)fprintf(stderr,
-		    "disk init info not in namelist\n");
-		return (0);
-	}
-	p = buf;
-	for (;; hp += sizeof hdev) {
-		(void)kvm_read(kd, hp, &hdev, sizeof hdev);
-		if (hdev.hp_driver == 0)
-			break;
-		if (hdev.hp_dk < 0 || hdev.hp_alive == 0 ||
-		    hdev.hp_cdriver == 0)
-			continue;
-		(void)kvm_read(kd, (u_long)hdev.hp_driver, &hdrv, sizeof hdrv);
-		(void)kvm_read(kd, (u_long)hdrv.d_name, name, sizeof name);
-		dr_name[hdev.hp_dk] = p;
-		p += sprintf(p, "%s%d", name, hdev.hp_unit) + 1;
-	}
-	return (1);
-}
-#endif /* hp300 || luna68k */
-
-#ifdef tahoe
-#include <tahoe/vba/vbavar.h>
-
-char *defdrives[] = { "dk0", "dk1", "dk2", 0 };
-
-int
-read_names()
-{
-	register char *p;
-	struct vba_device udev, *up;
-	struct vba_driver udrv;
-	char name[10];
-	static char buf[BUFSIZ];
-
-	up = (struct vba_device *)namelist[X_VBDINIT].n_value;
-	if (up == 0) {
-		(void) fprintf(stderr,
-		    "disk init info not in namelist\n");
-		return (0);
-	}
-	p = buf;
-	for (;; up += sizeof udev) {
-		(void)kvm_read(kd, up, &udev, sizeof udev);
-		if (udev.ui_driver == 0)
-			break;
-		if (udev.ui_dk < 0 || udev.ui_alive == 0)
-			continue;
-		(void)kvm_read(kd, udev.ui_driver, &udrv, sizeof udrv);
-		(void)kvm_read(kd, udrv.ud_dname, name, sizeof name);
-		dr_name[udev.ui_dk] = p;
-		p += sprintf(p, "%s%d", name, udev.ui_unit);
-	}
-	return (1);
-}
-#endif /* tahoe */
-
-#ifdef vax
-#include <vax/uba/ubavar.h>
-#include <vax/mba/mbavar.h>
-
-char *defdrives[] = { "hp0", "hp1", "hp2", 0 };
-
-int
-read_names()
-{
-	register char *p;
-	unsigned long mp, up;
-	struct mba_device mdev;
-	struct mba_driver mdrv;
-	struct uba_device udev;
-	struct uba_driver udrv;
-	char name[10];
-	static char buf[BUFSIZ];
-
-	mp = namelist[X_MBDINIT].n_value;
-	up = namelist[X_UBDINIT].n_value;
-	if (mp == 0 && up == 0) {
-		(void)fprintf(stderr,
-		    "disk init info not in namelist\n");
-		return (0);
-	}
-	p = buf;
-	if (mp)
-		for (;; mp += sizeof mdev) {
-			(void)kvm_read(kd, mp, &mdev, sizeof mdev);
-			if (mdev.mi_driver == 0)
-				break;
-			if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
-				continue;
-			(void)kvm_read(kd, mdev.mi_driver, &mdrv, sizeof mdrv);
-			(void)kvm_rea(kd, mdrv.md_dname, name, sizeof name);
-			dr_name[mdev.mi_dk] = p;
-			p += sprintf(p, "%s%d", name, mdev.mi_unit);
-		}
-	if (up)
-		for (;; up += sizeof udev) {
-			(void)kvm_read(kd, up, &udev, sizeof udev);
-			if (udev.ui_driver == 0)
-				break;
-			if (udev.ui_dk < 0 || udev.ui_alive == 0)
-				continue;
-			(void)kvm_read(kd, udev.ui_driver, &udrv, sizeof udrv);
-			(void)kvm_read(kd, udrv.ud_dname, name, sizeof name);
-			dr_name[udev.ui_dk] = p;
-			p += sprintf(p, "%s%d", name, udev.ui_unit);
-		}
-	return (1);
-}
-#endif /* vax */
-
-#ifdef sun
-#include <sundev/mbvar.h>
-
-int
-read_names()
-{
-	static int once = 0;
-	struct mb_device mdev;
-	struct mb_driver mdrv;
-	short two_char;
-	char *cp = (char *) &two_char;
-	register struct mb_device *mp;
-
-	mp = (struct mb_device *)namelist[X_MBDINIT].n_value;
-	if (mp == 0) {
-		(void)fprintf(stderr,
-		    "disk init info not in namelist\n");
-		return (0);
-	}
-	for (;; ++mp) {
-		(void)kvm_read(kd, mp++, &mdev, sizeof(mdev));
-		if (mdev.md_driver == 0)
-			break;
-		if (mdev.md_dk < 0 || mdev.md_alive == 0)
-			continue;
-		(void)kvm_read(kd, mdev.md_driver, &mdrv, sizeof(mdrv));
-		(void)kvm_read(kd, mdrv.mdr_dname, &two_char, sizeof(two_char));
-		(void)sprintf(dr_name[mdev.md_dk],
-		    "%c%c%d", cp[0], cp[1], mdev.md_unit);
-	}
-	return(1);
-}
-#endif /* sun */
-
-#if defined(mips)
-#include <pmax/dev/device.h>
-
-char *defdrives[] = { "rz0", "rz1", "rz2", "rz3", "rz4", "rz5", "rz6", 0 };
-
-int
-read_names()
-{
-	register char *p;
-	register u_long sp;
-	static char buf[BUFSIZ];
-	struct scsi_device sdev;
-	struct driver hdrv;
-	char name[10];
-
-	sp = namelist[X_SCSI_DINIT].n_value;
-	if (sp == 0) {
-		(void)fprintf(stderr, "disk init info not in namelist\n");
-		return (0);
-	}
-	p = buf;
-	for (;; sp += sizeof sdev) {
-		(void)kvm_read(kd, sp, &sdev, sizeof sdev);
-		if (sdev.sd_driver == 0)
-			break;
-		if (sdev.sd_dk < 0 || sdev.sd_alive == 0 ||
-		    sdev.sd_cdriver == 0)
-			continue;
-		(void)kvm_read(kd, (u_long)sdev.sd_driver, &hdrv, sizeof hdrv);
-		(void)kvm_read(kd, (u_long)hdrv.d_name, name, sizeof name);
-		dr_name[sdev.sd_dk] = p;
-		p += sprintf(p, "%s%d", name, sdev.sd_unit) + 1;
-	}
-	return (1);
-}
-#endif /* mips */
diff --git a/kextload.tproj/Makefile b/kdump.tproj/Makefile
similarity index 70%
rename from kextload.tproj/Makefile
rename to kdump.tproj/Makefile
index d09afc4..f09af30 100644
--- a/kextload.tproj/Makefile
+++ b/kdump.tproj/Makefile
@@ -7,28 +7,32 @@
 # and Makefile.postamble (both optional), and Makefile will include them.
 #
 
-NAME = kextload
+NAME = kdump
 
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Tool
 
-CFILES = kextload_main.c
+CFILES = kdump.c
 
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble kextload.8
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble kdump.1\
+            mkioctls syscalls.c
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
 CODE_GEN_STYLE = DYNAMIC
 MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /sbin
-WINDOWS_INSTALLDIR = /Library/Executables
-PDO_UNIX_INSTALLDIR = /bin
+NEXTSTEP_INSTALLDIR = /usr/bin
+WINDOWS_INSTALLDIR = /usr/bin
+PDO_UNIX_INSTALLDIR = /usr/bin
 LIBS = 
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
 
-FRAMEWORKS = -framework CoreFoundation -framework IOKit
+HEADER_PATHS = -I../ktrace.tproj
+NEXTSTEP_PB_CFLAGS = -DMACH_USER_API
+WINDOWS_PB_CFLAGS = -DMACH_USER_API
+PDO_UNIX_PB_CFLAGS = -DMACH_USER_API
 
 
 NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
diff --git a/kdump.tproj/Makefile.postamble b/kdump.tproj/Makefile.postamble
new file mode 100644
index 0000000..1e2ae06
--- /dev/null
+++ b/kdump.tproj/Makefile.postamble
@@ -0,0 +1,8 @@
+VPATH += :../ktrace.tproj
+
+ioctl.c: mkioctls
+	$(SHELL) mkioctls -s /usr/include > $(SFILE_DIR)/ioctl.c
+
+install-man-page:
+	install -d $(DSTROOT)/usr/share/man/man1
+	install -c -m 444 kdump.1 $(DSTROOT)/usr/share/man/man1/kdump.1
diff --git a/kdump.tproj/Makefile.preamble b/kdump.tproj/Makefile.preamble
new file mode 100644
index 0000000..1bf99f7
--- /dev/null
+++ b/kdump.tproj/Makefile.preamble
@@ -0,0 +1,7 @@
+KTRACE_CFILES = subr.c
+GENERATED_CFILES = ioctl.c
+OTHER_INITIAL_DEPENDS = $(GENERATED_CFILES)
+OTHER_OFILES = $(GENERATED_CFILES:.c=.o) $(KTRACE_CFILES:.c=.o)
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+AFTER_INSTALL += install-man-page
+-include ../Makefile.include
diff --git a/kdump.tproj/PB.project b/kdump.tproj/PB.project
new file mode 100644
index 0000000..1fbdcd4
--- /dev/null
+++ b/kdump.tproj/PB.project
@@ -0,0 +1,42 @@
+{
+    APPCLASS = NSApplication; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        HEADERSEARCH = (../ktrace.tproj); 
+        H_FILES = (); 
+        M_FILES = (); 
+        OTHER_LIBS = (); 
+        OTHER_LINKED = (kdump.c); 
+        OTHER_SOURCES = (
+            Makefile.preamble, 
+            Makefile, 
+            Makefile.postamble, 
+            kdump.1, 
+            mkioctls, 
+            syscalls.c
+        ); 
+    }; 
+    LANGUAGE = English; 
+    LOCALIZABLE_FILES = {}; 
+    NEXTSTEP_BUILDTOOL = make; 
+    NEXTSTEP_COMPILEROPTIONS = "-DMACH_USER_API"; 
+    NEXTSTEP_INSTALLDIR = /usr/bin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_MAINNIB = kdump; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = make; 
+    PDO_UNIX_COMPILEROPTIONS = "-DMACH_USER_API"; 
+    PDO_UNIX_INSTALLDIR = /usr/bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_MAINNIB = kdump; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = kdump; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = make; 
+    WINDOWS_COMPILEROPTIONS = "-DMACH_USER_API"; 
+    WINDOWS_INSTALLDIR = /usr/bin; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_MAINNIB = kdump; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/kdump.tproj/kdump.1 b/kdump.tproj/kdump.1
new file mode 100644
index 0000000..ab9c37a
--- /dev/null
+++ b/kdump.tproj/kdump.1
@@ -0,0 +1,102 @@
+.\" Copyright (c) 1990, 1993
+.\"	The Regents of the University of California.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"	@(#)kdump.1	8.1 (Berkeley) 6/6/93
+.\" $FreeBSD: src/usr.bin/kdump/kdump.1,v 1.5.2.2 2001/08/16 13:16:51 ru Exp $
+.\"
+.Dd June 6, 1993
+.Dt KDUMP 1
+.Os
+.Sh NAME
+.Nm kdump
+.Nd display kernel trace data
+.Sh SYNOPSIS
+.Nm
+.Op Fl dnlRT
+.Op Fl f Ar file
+.Op Fl m Ar maxdata
+.Op Fl t Op cnisuw
+.Sh DESCRIPTION
+The
+.Nm
+command displays the kernel trace files produced with
+.Xr ktrace 1
+in human readable format.
+By default, the file
+.Pa ktrace.out
+in the current directory is displayed.
+.Pp
+The options are as follows:
+.Bl -tag -width Fl
+.It Fl d
+Display all numbers in decimal.
+.It Fl f Ar file
+Display the specified file instead of
+.Pa ktrace.out .
+.It Fl l
+Loop reading the trace file, once the end-of-file is reached, waiting for
+more data.
+.It Fl m Ar maxdata
+Display at most
+.Ar maxdata
+bytes when decoding
+.Tn I/O .
+.It Fl n
+Suppress ad hoc translations.
+Normally
+.Nm
+tries to decode many system calls into a more human readable format.
+For example,
+.Xr ioctl 2
+values are replaced with the macro name and
+.Va errno
+values are replaced with the
+.Xr strerror 3
+string.
+Suppressing this feature yields a more consistent output format and is
+easily amenable to further processing.
+.It Fl R
+Display relative timestamps (time since previous entry).
+.It Fl T
+Display absolute timestamps for each entry (seconds since epoch).
+.It Fl t Ar cnisuw
+See the
+.Fl t
+option of
+.Xr ktrace 1 .
+.El
+.Sh SEE ALSO
+.Xr ktrace 1
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.4 .
diff --git a/kdump.tproj/kdump.c b/kdump.tproj/kdump.c
new file mode 100644
index 0000000..7f1238e
--- /dev/null
+++ b/kdump.tproj/kdump.c
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 1999, 2000-2001 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License').  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*-
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)kdump.c	8.1 (Berkeley) 6/6/93";
+#endif
+static const char rcsid[] =
+  "$FreeBSD: src/usr.bin/kdump/kdump.c,v 1.17 1999/12/29 05:05:33 peter Exp $";
+#endif /* not lint */
+
+#define KERNEL
+extern int errno;
+#include <sys/errno.h>
+#undef KERNEL
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/ktrace.h>
+#include <sys/ioctl.h>
+#include <sys/ptrace.h>
+#include <err.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <vis.h>
+#include "ktrace.h"
+
+int timestamp, decimal, fancy = 1, tail, maxdata;
+char *tracefile = DEF_TRACEFILE;
+struct ktr_header ktr_header;
+
+#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
+
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	int ch, ktrlen, size;
+	register void *m;
+	int trpoints = ALL_POINTS;
+
+	(void) setlocale(LC_CTYPE, "");
+
+	while ((ch = getopt(argc,argv,"f:dlm:nRTt:")) != -1)
+		switch((char)ch) {
+		case 'f':
+			tracefile = optarg;
+			break;
+		case 'd':
+			decimal = 1;
+			break;
+		case 'l':
+			tail = 1;
+			break;
+		case 'm':
+			maxdata = atoi(optarg);
+			break;
+		case 'n':
+			fancy = 0;
+			break;
+		case 'R':
+			timestamp = 2;	/* relative timestamp */
+			break;
+		case 'T':
+			timestamp = 1;
+			break;
+		case 't':
+			trpoints = getpoints(optarg);
+			if (trpoints < 0)
+				errx(1, "unknown trace point in %s", optarg);
+			break;
+		default:
+			usage();
+		}
+
+	if (argc > optind)
+		usage();
+
+	m = (void *)malloc(size = 1025);
+	if (m == NULL)
+		errx(1, "%s", strerror(ENOMEM));
+	if (!freopen(tracefile, "r", stdin))
+		err(1, "%s", tracefile);
+	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
+		if (trpoints & (1<<ktr_header.ktr_type))
+			dumpheader(&ktr_header);
+		if ((ktrlen = ktr_header.ktr_len) < 0)
+			errx(1, "bogus length 0x%x", ktrlen);
+		if (ktrlen > size) {
+			m = (void *)realloc(m, ktrlen+1);
+			if (m == NULL)
+				errx(1, "%s", strerror(ENOMEM));
+			size = ktrlen;
+		}
+		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
+			errx(1, "data too short");
+		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
+			continue;
+		switch (ktr_header.ktr_type) {
+		case KTR_SYSCALL:
+			ktrsyscall((struct ktr_syscall *)m);
+			break;
+		case KTR_SYSRET:
+			ktrsysret((struct ktr_sysret *)m);
+			break;
+		case KTR_NAMEI:
+			ktrnamei(m, ktrlen);
+			break;
+		case KTR_GENIO:
+			ktrgenio((struct ktr_genio *)m, ktrlen);
+			break;
+		case KTR_PSIG:
+			ktrpsig((struct ktr_psig *)m);
+			break;
+		case KTR_CSW:
+			ktrcsw((struct ktr_csw *)m);
+			break;
+		case KTR_USER:
+			ktruser(ktrlen, m);
+			break;
+		}
+		if (tail)
+			(void)fflush(stdout);
+	}
+}
+
+fread_tail(buf, size, num)
+	char *buf;
+	int num, size;
+{
+	int i;
+
+	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
+		(void)sleep(1);
+		clearerr(stdin);
+	}
+	return (i);
+}
+
+dumpheader(kth)
+	struct ktr_header *kth;
+{
+	static char unknown[64];
+	static struct timeval prevtime, temp;
+	char *type;
+
+	switch (kth->ktr_type) {
+	case KTR_SYSCALL:
+		type = "CALL";
+		break;
+	case KTR_SYSRET:
+		type = "RET ";
+		break;
+	case KTR_NAMEI:
+		type = "NAMI";
+		break;
+	case KTR_GENIO:
+		type = "GIO ";
+		break;
+	case KTR_PSIG:
+		type = "PSIG";
+		break;
+	case KTR_CSW:
+		type = "CSW";
+		break;
+	case KTR_USER:
+		type = "USER";
+		break;
+	default:
+		(void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
+		type = unknown;
+	}
+
+	(void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, kth->ktr_comm);
+	if (timestamp) {
+		if (timestamp == 2) {
+			temp = kth->ktr_time;
+			timevalsub(&kth->ktr_time, &prevtime);
+			prevtime = temp;
+		}
+		(void)printf("%ld.%06ld ",
+		    kth->ktr_time.tv_sec, kth->ktr_time.tv_usec);
+	}
+	(void)printf("%s  ", type);
+}
+
+#include <sys/syscall.h>
+#include "syscalls.c"
+int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
+
+static char *ptrace_ops[] = {
+	"PT_TRACE_ME",	"PT_READ_I",	"PT_READ_D",	"PT_READ_U",
+	"PT_WRITE_I",	"PT_WRITE_D",	"PT_WRITE_U",	"PT_CONTINUE",
+	"PT_KILL",	"PT_STEP",	"PT_ATTACH",	"PT_DETACH",
+};
+
+ktrsyscall(ktr)
+	register struct ktr_syscall *ktr;
+{
+	register narg = ktr->ktr_narg;
+	register register_t *ip;
+	char *ioctlname();
+
+	if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0)
+		(void)printf("[%d]", ktr->ktr_code);
+	else
+		(void)printf("%s", syscallnames[ktr->ktr_code]);
+	ip = &ktr->ktr_args[0];
+	if (narg) {
+		char c = '(';
+		if (fancy) {
+			if (ktr->ktr_code == SYS_ioctl) {
+				char *cp;
+				if (decimal)
+					(void)printf("(%ld", (long)*ip);
+				else
+					(void)printf("(%#lx", (long)*ip);
+				ip++;
+				narg--;
+				if ((cp = ioctlname(*ip)) != NULL)
+					(void)printf(",%s", cp);
+				else {
+					if (decimal)
+						(void)printf(",%ld", (long)*ip);
+					else
+						(void)printf(",%#lx ", (long)*ip);
+				}
+				c = ',';
+				ip++;
+				narg--;
+			} else if (ktr->ktr_code == SYS_ptrace) {
+				if (*ip < sizeof(ptrace_ops) /
+				    sizeof(ptrace_ops[0]) && *ip >= 0)
+					(void)printf("(%s", ptrace_ops[*ip]);
+#ifdef PT_GETREGS
+				else if (*ip == PT_GETREGS)
+					(void)printf("(%s", "PT_GETREGS");
+#endif
+#ifdef PT_SETREGS
+				else if (*ip == PT_SETREGS)
+					(void)printf("(%s", "PT_SETREGS");
+#endif
+#ifdef PT_GETFPREGS
+				else if (*ip == PT_GETFPREGS)
+					(void)printf("(%s", "PT_GETFPREGS");
+#endif
+#ifdef PT_SETFPREGS
+				else if (*ip == PT_SETFPREGS)
+					(void)printf("(%s", "PT_SETFPREGS");
+#endif
+#ifdef PT_GETDBREGS
+				else if (*ip == PT_GETDBREGS)
+					(void)printf("(%s", "PT_GETDBREGS");
+#endif
+#ifdef PT_SETDBREGS
+				else if (*ip == PT_SETDBREGS)
+					(void)printf("(%s", "PT_SETDBREGS");
+#endif
+				else
+					(void)printf("(%ld", (long)*ip);
+				c = ',';
+				ip++;
+				narg--;
+			}
+		}
+		while (narg) {
+			if (decimal)
+				(void)printf("%c%ld", c, (long)*ip);
+			else
+				(void)printf("%c%#lx", c, (long)*ip);
+			c = ',';
+			ip++;
+			narg--;
+		}
+		(void)putchar(')');
+	}
+	(void)putchar('\n');
+}
+
+ktrsysret(ktr)
+	struct ktr_sysret *ktr;
+{
+	register register_t ret = ktr->ktr_retval;
+	register int error = ktr->ktr_error;
+	register int code = ktr->ktr_code;
+
+	if (code >= nsyscalls || code < 0)
+		(void)printf("[%d] ", code);
+	else
+		(void)printf("%s ", syscallnames[code]);
+
+	if (error == 0) {
+		if (fancy) {
+			(void)printf("%d", ret);
+			if (ret < 0 || ret > 9)
+				(void)printf("/%#lx", (long)ret);
+		} else {
+			if (decimal)
+				(void)printf("%ld", (long)ret);
+			else
+				(void)printf("%#lx", (long)ret);
+		}
+	} else if (error == ERESTART)
+		(void)printf("RESTART");
+	else if (error == EJUSTRETURN)
+		(void)printf("JUSTRETURN");
+	else {
+		(void)printf("-1 errno %d", ktr->ktr_error);
+		if (fancy)
+			(void)printf(" %s", strerror(ktr->ktr_error));
+	}
+	(void)putchar('\n');
+}
+
+ktrnamei(cp, len)
+	char *cp;
+{
+	(void)printf("\"%.*s\"\n", len, cp);
+}
+
+ktrgenio(ktr, len)
+	struct ktr_genio *ktr;
+{
+	register int datalen = len - sizeof (struct ktr_genio);
+	register char *dp = (char *)ktr + sizeof (struct ktr_genio);
+	register char *cp;
+	register int col = 0;
+	register width;
+	char visbuf[5];
+	static screenwidth = 0;
+
+	if (screenwidth == 0) {
+		struct winsize ws;
+
+		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
+		    ws.ws_col > 8)
+			screenwidth = ws.ws_col;
+		else
+			screenwidth = 80;
+	}
+	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
+		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
+		datalen == 1 ? "" : "s");
+	if (maxdata && datalen > maxdata)
+		datalen = maxdata;
+	(void)printf("       \"");
+	col = 8;
+	for (;datalen > 0; datalen--, dp++) {
+		(void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
+		cp = visbuf;
+		/*
+		 * Keep track of printables and
+		 * space chars (like fold(1)).
+		 */
+		if (col == 0) {
+			(void)putchar('\t');
+			col = 8;
+		}
+		switch(*cp) {
+		case '\n':
+			col = 0;
+			(void)putchar('\n');
+			continue;
+		case '\t':
+			width = 8 - (col&07);
+			break;
+		default:
+			width = strlen(cp);
+		}
+		if (col + width > (screenwidth-2)) {
+			(void)printf("\\\n\t");
+			col = 8;
+		}
+		col += width;
+		do {
+			(void)putchar(*cp++);
+		} while (*cp);
+	}
+	if (col == 0)
+		(void)printf("       ");
+	(void)printf("\"\n");
+}
+
+char *signames[] = {
+	"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",	/*  1 - 6  */
+	"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",		/*  7 - 12 */
+	"PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",		/* 13 - 18 */
+	"CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",		/* 19 - 24 */
+	"XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",	/* 25 - 30 */
+	"USR2", NULL,						/* 31 - 32 */
+};
+
+ktrpsig(psig)
+	struct ktr_psig *psig;
+{
+	(void)printf("SIG%s ", signames[psig->signo]);
+	if (psig->action == SIG_DFL)
+		(void)printf("SIG_DFL\n");
+	else
+		(void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n",
+		    (u_long)psig->action, psig->mask, psig->code);
+}
+
+ktrcsw(cs)
+	struct ktr_csw *cs;
+{
+	(void)printf("%s %s\n", cs->out ? "stop" : "resume",
+		cs->user ? "user" : "kernel");
+}
+
+ktruser(len, p)
+	int len;
+	unsigned char *p;
+{
+	(void)printf("%d ", len);
+	while (len--)
+		(void)printf(" %02x", *p++);
+	(void)printf("\n");
+		
+}
+
+usage()
+{
+	(void)fprintf(stderr,
+	    "usage: kdump [-dnlRT] [-f trfile] [-m maxdata] [-t [cnisuw]]\n");
+	exit(1);
+}
diff --git a/kdump.tproj/mkioctls b/kdump.tproj/mkioctls
new file mode 100644
index 0000000..53c8afd
--- /dev/null
+++ b/kdump.tproj/mkioctls
@@ -0,0 +1,91 @@
+set -e
+
+# $FreeBSD: src/usr.bin/kdump/mkioctls,v 1.15.2.3 2001/04/07 11:09:28 ru Exp $
+
+if [ "x$1" = "x-s" ]; then
+	use_switch=1
+	shift
+else
+	use_switch=0
+fi
+
+if [ -z "$1" ]; then
+	echo "usage: sh $0 [-s] include-dir"
+	exit 1
+fi
+
+LC_ALL=C; export LC_ALL
+
+# Build a list of headers that have ioctls in them.
+# XXX should we use an ANSI cpp?
+# XXX netipx conflicts with netns (leave out netns).
+ioctl_includes=`
+	cd $1
+	find * -name '*.h' |
+		egrep -v '^(netns)/' |
+		egrep -v 'if_atm' |
+		egrep -v 'disklabel' |
+		egrep -v 'if_ppp' |
+		egrep -v 'bpf' |
+		egrep -v '^(netiso)/' |
+		egrep -v '^(netccitt)/' |
+		xargs egrep -l \
+'^#[ 	]*define[ 	]+[A-Za-z_][A-Za-z0-9_]*[ 	]+_IO[^a-z0-9_]' |
+		sed -e 's/^/#include </' -e s'/$/>/' 
+`
+
+echo "/* XXX obnoxious prerequisites. */"
+echo "#define COMPAT_43 1"
+echo "#include <sys/param.h>"
+echo "#include <sys/socket.h>"
+echo "#include <sys/time.h>"
+echo "#include <sys/tty.h>"
+echo "#include <net/ethernet.h>"
+echo "#include <net/if.h>"
+echo "#include <net/if_var.h>"
+echo "#include <net/route.h>"
+echo "#include <netinet/in.h>"
+echo "#include <netinet/ip_compat.h>"
+echo "#include <netinet/ip_mroute.h>"
+echo "#include <netinet6/in6_var.h>"
+echo "#include <netinet6/nd6.h>"
+echo "#include <netinet6/ip6_mroute.h>"
+echo "#include <netat/appletalk.h>"
+echo "#include <stdio.h>"
+echo ""
+echo "$ioctl_includes"
+echo ""
+
+echo "$ioctl_includes" |
+	cc -no-cpp-precomp -E -I$1 -dM - |
+	awk -v use_switch="$use_switch" '
+BEGIN {
+	print "char *"
+	print "ioctlname(register_t val)"
+	print "{"
+	print ""
+	if (use_switch)
+		print "\tswitch(val) {"
+}
+
+/^#[ 	]*define[ 	]+[A-Za-z_][A-Za-z0-9_]*[ 	]+_IO/ {
+	
+	# find where the name starts
+	for (i = 1; i <= NF; i++)
+		if ($i ~ /define/)
+			break;
+	++i;
+	# 
+	if (use_switch)
+		printf("\tcase %s:\n\t\treturn(\"%s\");\n", $i, $i);
+	else
+		printf("\tif (val ==  %s)\n\t\treturn(\"%s\");\n", $i, $i);
+
+}
+END {
+	if (use_switch)
+		print "\t}"
+	print "\n\treturn(NULL);"
+	print "}"
+}
+'
diff --git a/kdump.tproj/syscalls.c b/kdump.tproj/syscalls.c
new file mode 100644
index 0000000..71a9215
--- /dev/null
+++ b/kdump.tproj/syscalls.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* Copyright (c) 1992,1995-1999 Apple Computer, Inc.  All rights resereved. */
+
+char *syscallnames[] = {
+	"syscall",			/* 0 = syscall */
+	"exit",				/* 1 = exit */
+	"fork",				/* 2 = fork */
+	"read",				/* 3 = read */
+	"write",			/* 4 = write */
+	"open",				/* 5 = open */
+	"close",			/* 6 = close */
+	"wait4",			/* 7 = wait4 */
+	"obs_creat",		/* 8 = old creat */
+	"link",				/* 9 = link */
+	"unlink",			/* 10 = unlink */
+	"obs_execv",		/* 11 = obsolete execv */
+	"chdir",			/* 12 = chdir */
+	"fchdir",			/* 13 = fchdir */
+	"mknod",			/* 14 = mknod */
+	"chmod",			/* 15 = chmod */
+	"chown",			/* 16 = chown */
+	"obs_break",		/* 17 = obsolete break */
+	"obs_getfsstat",	/* 18 = obsolete getfsstat */
+	"old_lseek",		/* 19 = old lseek */
+	"getpid",			/* 20 = getpid */
+	"obs_mount",		/* 21 = obsolete mount */
+	"obs_unmount",		/* 22 = obsolete unmount */
+	"setuid",			/* 23 = setuid */
+	"getuid",			/* 24 = getuid */
+	"geteuid",			/* 25 = geteuid */
+	"ptrace",			/* 26 = ptrace */
+	"recvmsg",			/* 27 = recvmsg */
+	"sendmsg",			/* 28 = sendmsg */
+	"recvfrom",			/* 29 = recvfrom */
+	"accept",			/* 30 = accept */
+	"getpeername",		/* 31 = getpeername */
+	"getsockname",		/* 32 = getsockname */
+	"access",			/* 33 = access */
+	"chflags",			/* 34 = chflags */
+	"fchflags",			/* 35 = fchflags */
+	"sync",				/* 36 = sync */
+	"kill",				/* 37 = kill */
+	"obs_stat",			/* 38 = old stat */
+	"getppid",			/* 39 = getppid */
+	"obs_lstat",		/* 40 = old lstat */
+	"dup",				/* 41 = dup */
+	"pipe",				/* 42 = pipe */
+	"getegid",			/* 43 = getegid */
+	"profil",			/* 44 = profil */
+	"ktrace",			/* 45 = ktrace */
+	"sigaction",		/* 46 = sigaction */
+	"getgid",			/* 47 = getgid */
+	"sigprocmask",		/* 48 = sigprocmask */
+	"getlogin",			/* 49 = getlogin */
+	"setlogin",			/* 50 = setlogin */
+	"acct",				/* 51 = acct */
+	"sigpending",		/* 52 = sigpending */
+	"sigaltstack",		/* 53 = sigaltstack */
+	"ioctl",			/* 54 = ioctl */
+	"reboot",			/* 55 = reboot */
+	"revoke",			/* 56 = revoke */
+	"symlink",			/* 57 = symlink */
+	"readlink",			/* 58 = readlink */
+	"execve",			/* 59 = execve */
+	"umask",			/* 60 = umask */
+	"chroot",			/* 61 = chroot */
+	"obs_fstat",		/* 62 = old fstat */
+	"#63",				/* 63 = reserved */
+	"obs_getpagesize",	/* 64 = old getpagesize */
+	"msync",			/* 65 = msync */
+	"vfork",			/* 66 = vfork */
+	"obs_vread",		/* 67 = obsolete vread */
+	"obs_vwrite",		/* 68 = obsolete vwrite */
+	"sbrk",				/* 69 = sbrk */
+	"sstk",				/* 70 = sstk */
+	"obs_mmap",			/* 71 = old mmap */
+	"obs_vadvise",		/* 72 = obsolete vadvise */
+	"munmap",			/* 73 = munmap */
+	"mprotect",			/* 74 = mprotect */
+	"madvise",			/* 75 = madvise */
+	"#76",				/* 76 = obsolete vhangup */
+	"#77",				/* 77 = obsolete vlimit */
+	"mincore",			/* 78 = mincore */
+	"getgroups",		/* 79 = getgroups */
+	"setgroups",		/* 80 = setgroups */
+	"getpgrp",			/* 81 = getpgrp */
+	"setpgid",			/* 82 = setpgid */
+	"setitimer",		/* 83 = setitimer */
+	"old_wait",			/* 84 = old wait */
+	"obs_swapon",		/* 85 = swapon */
+	"getitimer",		/* 86 = getitimer */
+	"obs_gethostname",	/* 87 = old gethostname */
+	"obs_sethostname",	/* 88 = old sethostname */
+	"getdtablesize",	/* 89 = getdtablesize */
+	"dup2",				/* 90 = dup2 */
+	"#91",				/* 91 = getdopt */
+	"fcntl",			/* 92 = fcntl */
+	"select",			/* 93 = select */
+	"#94",				/* 94 = setdopt */
+	"fsync",			/* 95 = fsync */
+	"setpriority",		/* 96 = setpriority */
+	"socket",			/* 97 = socket */
+	"connect",			/* 98 = connect */
+	"obs_accept",		/* 99 = old accept */
+	"getpriority",		/* 100 = getpriority */
+	"old_send",			/* 101 = old send */
+	"old_recv",			/* 102 = old recv */
+	"sigreturn",		/* 103 = sigreturn */
+	"bind",				/* 104 = bind */
+	"setsockopt",		/* 105 = setsockopt */
+	"listen",			/* 106 = listen */
+	"#107",				/* 107 = obsolete vtimes */
+	"obs_sigvec",		/* 108 = old sigvec */
+	"obs_sigblock",		/* 109 = old sigblock */
+	"obs_sigsetmask",	/* 110 = old sigsetmask */
+	"sigsuspend",		/* 111 = sigsuspend */
+	"obs_sigstack",		/* 112 = old sigstack */
+	"obs_recvmsg",		/* 113 = old recvmsg */
+	"obs_sendmsg",		/* 114 = old sendmsg */
+	"#115",				/* 115 = obsolete vtrace */
+	"gettimeofday",		/* 116 = gettimeofday */
+	"getrusage",		/* 117 = getrusage */
+	"getsockopt",		/* 118 = getsockopt */
+	"#119",				/* 119 = nosys */
+	"readv",			/* 120 = readv */
+	"writev",			/* 121 = writev */
+	"settimeofday",		/* 122 = settimeofday */
+	"fchown",			/* 123 = fchown */
+	"fchmod",			/* 124 = fchmod */
+	"obs_recvfrom",		/* 125 = old recvfrom */
+	"obs_setreuid",		/* 126 = old setreuid */
+	"obs_setregid",		/* 127 = old setregid */
+	"rename",			/* 128 = rename */
+	"obs_truncate",		/* 129 = old truncate */
+	"obs_ftruncate",	/* 130 = old ftruncate */
+	"flock",			/* 131 = flock */
+	"mkfifo",			/* 132 = mkfifo */
+	"sendto",			/* 133 = sendto */
+	"shutdown",			/* 134 = shutdown */
+	"socketpair",		/* 135 = socketpair */
+	"mkdir",			/* 136 = mkdir */
+	"rmdir",			/* 137 = rmdir */
+	"utimes",			/* 138 = utimes */
+	"futimes",			/* 139 = futimes */
+	"adjtime",			/* 140 = adjtime */
+	"obs_getpeername",	/* 141 = old getpeername */
+	"obs_gethostid",	/* 142 = old gethostid */
+	"#143",				/* 143 = old sethostid */
+	"obs_getrlimit",	/* 144 = old getrlimit */
+	"obs_setrlimit",	/* 145 = old setrlimit */
+	"obs_killpg",		/* 146 = old killpg */
+	"setsid",			/* 147 = setsid */
+	"#148",				/* 148 = obsolete setquota */
+	"#149",				/* 149 = obsolete qquota */
+	"obs_getsockname",	/* 150 = old getsockname */
+	"#151",				/* 151 = nosys */
+	"setprivexec",		/* 152 = setprivexec */
+	"pread",			/* 153 = pread */
+	"pwrite",			/* 154 = pwrite */
+	"nfssvc",			/* 155 = nfssvc */
+	"getdirentries",	/* 156 =getdirentries */
+	"statfs",			/* 157 = statfs */
+	"fstatfs",			/* 158 = fstatfs */
+	"unmount",			/* 159 = unmount */
+	"#160",				/* 160 = obsolete async_daemon */
+	"getfh",			/* 161 = getfh */
+	"obs_getdomainname",/* 162 = old getdomainname */
+	"obs_setdomainname",/* 163 = old setdomainname */
+	"#164",				/* 164 */
+	"quotactl",			/* 165 = quotactl */
+	"#166",				/* 166 = obsolete exportfs */
+	"mount",			/* 167 = mount */
+	"#168",				/* 168 = obsolete ustat */
+	"#169",				/* 169 = nosys */
+	"#170",				/* 170 = obsolete table */
+	"obs_wait3",		/* 171 = old wait3 */
+	"#172",				/* 172 = obsolete rpause */
+	"#173",				/* 173 = nosys */
+	"#174",				/* 174 = obsolete getdents */
+	"#175",				/* 175 = nosys */
+	"add_profil",		/* 176 = add_profil */ /* NeXT */
+	"#177",				/* 177 = nosys */
+	"#178",				/* 178 = nosys */
+	"#179",				/* 179 = nosys */
+	"kdebug_trace",		/* 180 = kdebug_trace */
+	"setgid",			/* 181 = setgid */
+	"setegid",			/* 182 = setegid */
+	"seteuid",			/* 183 = seteuid */
+	"#184",				/* 184 = nosys */
+	"#185",				/* 185 = nosys */
+	"#186",				/* 186 = nosys */
+	"#187",				/* 187 = nosys */
+	"stat",				/* 188 = stat */
+	"fstat",			/* 189 = fstat */
+	"lstat",			/* 190 = lstat */
+	"pathconf",			/* 191 = pathconf */
+	"fpathconf",		/* 192 = fpathconf */
+	"obs_getfsstat",	/* 193 = old getfsstat */
+	"getrlimit",		/* 194 = getrlimit */
+	"setrlimit",		/* 195 = setrlimit */
+	"getdirentries",	/* 196 = getdirentries */
+	"mmap",				/* 197 = mmap */
+	"#198",				/* 198 = __syscall */
+	"lseek",			/* 199 = lseek */
+	"truncate",			/* 200 = truncate */
+	"ftruncate",		/* 201 = ftruncate */
+	"__sysctl",			/* 202 = __sysctl */
+	"mlock",			/* 203 = mlock */
+	"munlock",			/* 204 = munlock */
+	"undelete",			/* 205 = undelete */
+	"ATsocket",			/* 206 = ATsocket */
+	"ATgetmsg",			/* 207 = ATgetmsg */
+	"ATputmsg",			/* 208 = ATputmsg */
+	"ATPsndreq",		/* 209 = ATPsndreq */
+	"ATPsndrsp",		/* 210 = ATPsndrsp */
+	"ATPgetreq",		/* 211 = ATPgetreq */
+	"ATPgetrsp",		/* 212 = ATPgetrsp */
+	"#213",				/* 213 = Reserved for AppleTalk */
+	"#214",				/* 214 = Reserved for AppleTalk */
+	"#215",				/* 215 = Reserved for AppleTalk */
+	"#216",				/* 216 = Reserved */
+	"#217",				/* 217 = Reserved */
+	"#218",				/* 218 = Reserved */
+	"#219",				/* 219 = Reserved */
+	"getattrlist",		/* 220 = getattrlist */
+	"setattrlist",		/* 221 = setattrlist */
+	"getdirentriesattr",	/* 222 = getdirentriesattr */
+	"exchangedata",		/* 223 = exchangedata */
+	"checkuseraccess",	/* 224 - checkuseraccess */
+	"searchfs",			/* 225 = searchfs */
+	"delete",			/* 226 = private delete call */
+	"copyfile",			/* 227 = copyfile  */
+	"#228",				/* 228 = nosys */
+	"#229",				/* 229 = nosys */
+	"#230",				/* 230 = reserved for AFS */
+	"watchevent",		/* 231 = watchevent */
+	"waitevent",		/* 232 = waitevent */
+	"modwatch",			/* 233 = modwatch */
+	"#234",				/* 234 = nosys */
+	"#235",				/* 235 = nosys */
+	"#236",				/* 236 = nosys */
+	"#237",				/* 237 = nosys */
+	"#238",				/* 238 = nosys */
+	"#239",				/* 239 = nosys */
+	"#240",				/* 240 = nosys */
+	"#241",				/* 241 = nosys */
+	"fsctl",			/* 242 = fsctl */
+	"#243",				/* 243 = nosys */
+	"#244",				/* 244 = nosys */
+	"#245",				/* 245 = nosys */
+	"#246",				/* 246 = nosys */
+	"#247",				/* 247 = nosys */
+	"#248",				/* 248 = nosys */
+	"#249",				/* 249 = nosys */
+	"minherit",			/* 250 = minherit */
+	"semsys",			/* 251 = semsys */
+	"msgsys",			/* 252 = msgsys */
+	"shmsys",			/* 253 = shmsys */
+	"semctl",			/* 254 = semctl */
+	"semget",			/* 255 = semget */
+	"semop",			/* 256 = semop */
+	"semconfig",		/* 257 = semconfig */
+	"msgctl",			/* 258 = msgctl */
+	"msgget",			/* 259 = msgget */
+	"msgsnd",			/* 260 = msgsnd */
+	"msgrcv",			/* 261 = msgrcv */
+	"shmat",			/* 262 = shmat */
+	"shmctl",			/* 263 = shmctl */
+	"shmdt",			/* 264 = shmdt */
+	"shmget",			/* 265 = shmget */
+	"shm_open",			/* 266 = shm_open */
+	"shm_unlink",		/* 267 = shm_unlink */
+	"sem_open",			/* 268 = sem_open */
+	"sem_close",		/* 269 = sem_close */
+	"sem_unlink",		/* 270 = sem_unlink */
+	"sem_wait",			/* 271 = sem_wait */
+	"sem_trywait",		/* 272 = sem_trywait */
+	"sem_post",			/* 273 = sem_post */
+	"sem_getvalue",		/* 274 = sem_getvalue */
+	"sem_init",			/* 275 = sem_init */
+	"sem_destroy",		/* 276 = sem_destroy */
+	"#277",				/* 277 = nosys */
+	"#278",				/* 278 = nosys */
+	"#279",				/* 279 = nosys */
+	"#280",				/* 280 = nosys */
+	"#281",				/* 281 = nosys */
+	"#282",				/* 282 = nosys */
+	"#283",				/* 283 = nosys */
+	"#284",				/* 284 = nosys */
+	"#285",				/* 285 = nosys */
+	"#286",				/* 286 = nosys */
+	"#287",				/* 287 = nosys */
+	"#288",				/* 288 = nosys */
+	"#289",				/* 289 = nosys */
+	"#290",				/* 290 = nosys */
+	"#291",				/* 291 = nosys */
+	"#292",				/* 292 = nosys */
+	"#293",				/* 293 = nosys */
+	"#294",				/* 294 = nosys */
+	"#295",				/* 295 = nosys */
+	"load_shared_file",	/* 296 = load_shared_file */
+	"reset_shared_file",	/* 297 = reset_shared_file */
+	"new_system_shared_regions",	/* 298 = new_system_shared_regions */
+	"#299",				/* 299 = nosys */
+	"#300",				/* 300 = modnext */
+	"#301",				/* 301 = modstat */
+	"#302",				/* 302 = modfnext */
+	"#303",				/* 303 = modfind */
+	"#304",				/* 304 = kldload */
+	"#305",				/* 305 = kldunload */
+	"#306",				/* 306 = kldfind */
+	"#307",				/* 307 = kldnext */
+	"#308",				/* 308 = kldstat */
+	"#309",				/* 309 = kldfirstmod */
+	"#310",				/* 310 = getsid */
+	"#311",				/* 311 = setresuid */
+	"#312",				/* 312 = setresgid */
+	"#313",				/* 313 = obsolete signanosleep */
+	"#314",				/* 314 = aio_return */
+	"#315",				/* 315 = aio_suspend */
+	"#316",				/* 316 = aio_cancel */
+	"#317",				/* 317 = aio_error */
+	"#318",				/* 318 = aio_read */
+	"#319",				/* 319 = aio_write */
+	"#320",				/* 320 = lio_listio */
+	"#321",				/* 321 = yield */
+	"#322",				/* 322 = thr_sleep */
+	"#323",				/* 323 = thr_wakeup */
+	"mlockall",			/* 324 = mlockall */
+	"munlockall",		/* 325 = munlockall */
+	"#326",				/* 326 */
+	"issetugid",		/* 327 = issetugid */
+	"__pthread_kill",	/* 328  = __pthread_kill */
+	"pthread_sigmask",	/* 329  = pthread_sigmask */
+	"sigwait",			/* 330 = sigwait */
+	"#331",				/* 331 */
+	"#332",				/* 332 */
+	"#333",				/* 333 */
+	"#334",				/* 334 */
+	"utrace",			/* 335 = utrace */
+	"#336",				/* 336 */
+	"#337",				/* 337 */
+	"#338",				/* 338 */
+	"#339",				/* 339 */
+	"#340",				/* 340 */
+	"#341",				/* 341 */
+	"#342",				/* 342 */
+	"#343",				/* 343 */
+	"#344",				/* 344 */
+	"#345",				/* 345 */
+	"#346",				/* 346 */
+	"#347",				/* 347 */
+	"#348",				/* 348 */
+	"#349"				/* 349 */
+};
diff --git a/kextd.tproj/GetSymbolFromPEF.h b/kextd.tproj/GetSymbolFromPEF.h
deleted file mode 100644
index 378eca6..0000000
--- a/kextd.tproj/GetSymbolFromPEF.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
-	File:		GetSymbolFromPEF.h
-
-	Contains:	xxx put contents here xxx
-
-	Written by:	Jeffrey Robbin
-
-	Copyright:	© 1994 by Apple Computer, Inc., all rights reserved.
-
-	Change History (most recent first):
-
-		 <2>	 9/20/94	TS		Dump the globals!
-		 <1>	  9/6/94	TS		first checked in
-
-*/
-
-#ifndef __GETSYMBOLFROMPEF__
-#define __GETSYMBOLFROMPEF__
-
-//#include <Types.h>
-
-#pragma options align=mac68k
-
-#define NewPtrSys(a)	malloc(a)
-#define DisposePtr(a)	free(a)
-
-/*
-	Container information
-*/
-
-struct ContainerHeader {					/* File/container header layout:					*/
-	unsigned long	magicCookie;			/* 		PEF container magic cookie					*/
-	unsigned long	containerID;			/* 		'peff'										*/
-	unsigned long	architectureID;			/* 		'pwpc' | 'm68k'							 	*/
-	unsigned long	versionNumber;			/* 		format version number						*/
-	unsigned long	dateTimeStamp;			/* 		date/time stamp (Mac format)				*/
-	unsigned long	oldDefVersion;			/*		old definition version number 				*/
-	unsigned long	oldImpVersion;			/* 		old implementation version number 			*/
-	unsigned long	currentVersion;			/* 		current version number 						*/
-	short			nbrOfSections;			/* 		nbr of sections (rel. 1)					*/
-	short			loadableSections;		/* 		nbr of loadable sectionsfor execution		*/
-	                                  		/*		(= nbr of 1st non-loadable section)		 	*/
-	LogicalAddress	memoryAddress;			/* 		location this container was last loaded 	*/
-};
-typedef struct ContainerHeader ContainerHeader, *ContainerHeaderPtr;
-
-#define	kMagic1		'joy!'
-#define	kMagic2		'peff'
-
-
-/*
-	Section information
-*/
-
-struct SectionHeader {						/* Section header layout:						*/
-	long			sectionName;			/* 		section name (str tbl container offset)	*/
-	unsigned long	sectionAddress;			/* 		preferred base address for the section 	*/
-	long			execSize;				/* 		execution (byte) size including 0 init)	*/
-	long			initSize;				/* 		init (byte) size before 0 init			*/
-	long			rawSize;				/* 		raw data size (bytes)					*/
-	long			containerOffset;		/* 		container offest to section's raw data 	*/
-	unsigned char	regionKind;				/* 		section/region classification 			*/
-	unsigned char	shareKind;				/* 		sharing classification 					*/
-	unsigned char	alignment;				/* 		log 2 alignment							*/
-	unsigned char	reserved;				/*		<reserved>								*/
-};
-typedef struct SectionHeader SectionHeader, *SectionHeaderPtr;
-
-											/* regionKind section classification:			*/
-											/* 		loadable sections						*/
-#define kCodeSection 		0U 				/*				code section					*/
-#define kDataSection 		1U				/*				data section					*/
-#define kPIDataSection 		2U				/*				"pattern" initialized data		*/
-#define kConstantSection 	3U				/*				read-only data					*/
-#define kExecDataSection 	6U				/*				"self modifying" code (!?)		*/
-											/*		non-loadable sections					*/
-#define kLoaderSection 		4U				/*				loader							*/
-#define kDebugSection 		5U				/*				debugging info					*/
-#define kExceptionSection	7U				/*				exception data					*/
-#define kTracebackSection	8U				/*				traceback data					*/
-
-
-/*
-	Loader Information
-*/
-
-struct LoaderHeader {						/* Loader raw data section header layout:		*/
-	long entrySection;						/* 		entry point section number				*/
-	long entryOffset;						/* 		entry point descr. ldr section offset	*/
-	long initSection;						/* 		init routine section number				*/
-	long initOffset;						/* 		init routine descr. ldr section offset	*/
-	long termSection;						/* 		term routine section number				*/
-	long termOffset;						/* 		term routine descr. ldr section offset	*/
-	long nbrImportIDs;						/* 		nbr of import container id entries 		*/
-	long nbrImportSyms;						/* 		nbr of import symbol table entries 		*/
-	long nbrRelocSects;						/* 		nbr of relocation sections (headers)	*/
-	long relocsOffset;						/* 		reloc. instructions ldr section offset	*/
-	long strTblOffset;						/* 		string table ldr section offset			*/
-  	long slotTblOffset;      				/* 		hash slot table ldr section offset		*/
-	long hashSlotTblSz;       				/* 		log 2 of nbr of hash slot entries 		*/
-	long nbrExportSyms;						/* 		nbr of export symbol table entries 		*/
-};
-typedef struct LoaderHeader LoaderHeader, *LoaderHeaderPtr;
-
-struct LoaderHashSlotEntry {				/* Loader export hash slot table entry layout:	*/
-	unsigned long slotEntry;				/* 		chain count (0:13), chain index (14:31)	*/
-};
-typedef struct LoaderHashSlotEntry LoaderHashSlotEntry, *LoaderHashSlotEntryPtr;
-
-struct LoaderExportChainEntry {				/* Loader export hash chain tbl entry layout:	*/
-	union {
-		unsigned long _hashWord;			/* 		name length and hash value				*/
-		struct {
-			unsigned short _nameLength;		/*		name length is top half of hash word	*/
-			unsigned short doNotUseThis;	/*		this field should never be accessed!	*/
-		} _h_h;
-	} _h;
-};
-typedef struct LoaderExportChainEntry LoaderExportChainEntry, *LoaderExportChainEntryPtr;
-
-struct ExportSymbolEntry {					/* Loader export symbol table entry layout:		*/
-	unsigned long	class_and_name;			/* 		symClass (0:7), nameOffset (8:31)		*/
-	long			address;				/* 		ldr section offset to exported symbol 	*/
-	short			sectionNumber;			/*		section nbr that this export belongs to	*/
-};
-typedef struct ExportSymbolEntry ExportSymbolEntry, *ExportSymbolEntryPtr;
-
-
-
-/*
-	Unpacking Information
-*/
-
-											/* "pattern" initialized data opcodes:			 */
-#define kZero 					0U			/*		zero (clear) bytes						*/
-#define kBlock 					1U			/*		block transfer bytes					*/
-#define kRepeat 				2U			/*		repeat block xfer	bytes				*/
-#define kRepeatBlock 			3U			/* 		repeat block xfer with contant prefix	*/
-#define kRepeatZero  			4U			/*		repeat block xfer with contant prefix 0	*/
-
-#define kOpcodeShift 			0x05U		/* shift to access opcode						*/
-#define kFirstOperandMask 		0x1FU		/* mask to access 1st operand (count)			*/
-
-#define PIOP(x) 	(unsigned char)((x) >> kOpcodeShift)	/* extract opcode				*/
-#define PICNT(x) (long)((x) & kFirstOperandMask)			/* extract 1st operand (count)	*/
-
-/* The following macros are used for extracting count value operands from pidata...			*/
-
-#define kCountShift				0x07UL		/* value shift to concat count bytes			*/
-#define kCountMask				0x7FUL		/* mask to extract count bits from a byte		*/
-
-#define IS_LAST_PICNT_BYTE(x) (((x) & 0x80U) == 0)			/* true if last count byte		*/
-
-#define CONCAT_PICNT(value, x) (((value)<<kCountShift) | ((x) & kCountMask))
-
-
-
-/*
-	Function Prototypes
-*/
-
-static OSStatus GetSymbolFromPEF (	StringPtr		theSymbolName,
-							LogicalAddress	thePEFPtr,
-							LogicalAddress	theSymbolPtr,
-							ByteCount		theSymbolSize);
-
-static Boolean	SymbolCompare (	StringPtr		theLookedForSymbol,
-						StringPtr		theExportSymbol,
-						unsigned long	theExportSymbolLength);
-						
-static OSErr UnpackPiData (LogicalAddress		thePEFPtr,
-					SectionHeaderPtr	sectionHeaderPtr,
-					LogicalAddress *	theData);
-
-static unsigned char PEFGetNextByte (unsigned char** rawBuffer, long* rawBufferRemaining);
-
-static unsigned long PEFGetCount(unsigned char** rawBuffer, long* rawBufferRemaining);
-
-
-#pragma options align=reset
-
-#endif
diff --git a/kextd.tproj/KEXTD.c b/kextd.tproj/KEXTD.c
deleted file mode 100644
index 2030b48..0000000
--- a/kextd.tproj/KEXTD.c
+++ /dev/null
@@ -1,1838 +0,0 @@
-#define CFRUNLOOP_NEW_API 1
-
-#include "KEXTD.h"
-#include "PTLock.h"
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOKitServer.h>
-#include <IOKit/IOCFSerialize.h>
-#include <IOKit/IOCFURLAccess.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <mach/mach.h>
-#include <mach/mach_host.h>
-#include <mach/bootstrap.h>
-#include <mach/kmod.h>
-#include <syslog.h>
-
-#include <CoreFoundation/CFPriv.h>              // for _CFRunLoopSetCurrent();
-
-#define TIMER_PERIOD_S 10
-#define LOOKAPPLENDRV 1
-
-static Boolean gDebug;
-static void KEXTdaemonSignal(void);
-
-// from kernserv/queue.h   now kern/queue.h
-
-/*
- *	A generic doubly-linked list (queue).
- */
-
-struct queue_entry {
-        struct queue_entry	*next;		/* next element */
-        struct queue_entry	*prev;		/* previous element */
-};
-
-typedef struct queue_entry	*queue_t;
-typedef	struct queue_entry	queue_head_t;
-typedef	struct queue_entry	queue_chain_t;
-typedef	struct queue_entry	*queue_entry_t;
-
-/*
- *	Macro:		queue_init
- *	Function:
- *		Initialize the given queue.
- *	Header:
- *		void queue_init(q)
- *			queue_t		q;	\* MODIFIED *\
- */
-#define	queue_init(q)	((q)->next = (q)->prev = q)
-
-/*
- *	Macro:		queue_first
- *	Function:
- *		Returns the first entry in the queue,
- *	Header:
- *		queue_entry_t queue_first(q)
- *			queue_t	q;		\* IN *\
- */
-#define	queue_first(q)	((q)->next)
-
-/*
- *	Macro:		queue_next
- *	Header:
- *		queue_entry_t queue_next(qc)
- *			queue_t qc;
- */
-#define	queue_next(qc)	((qc)->next)
-
-/*
- *	Macro:		queue_end
- *	Header:
- *		boolean_t queue_end(q, qe)
- *			queue_t q;
- *			queue_entry_t qe;
- */
-#define	queue_end(q, qe)	((q) == (qe))
-
-#define	queue_empty(q)		queue_end((q), queue_first(q))
-
-/*
- *	Macro:		queue_enter
- *	Header:
- *		void queue_enter(q, elt, type, field)
- *			queue_t q;
- *			<type> elt;
- *			<type> is what's in our queue
- *			<field> is the chain field in (*<type>)
- */
-#define queue_enter(head, elt, type, field)			\
-do {							\
-        if (queue_empty((head))) {				\
-                (head)->next = (queue_entry_t) elt;		\
-                (head)->prev = (queue_entry_t) elt;		\
-                (elt)->field.next = head;			\
-                (elt)->field.prev = head;			\
-        }							\
-        else {							\
-                register queue_entry_t prev;			\
-                                                                \
-                prev = (head)->prev;				\
-                (elt)->field.prev = prev;			\
-                (elt)->field.next = head;			\
-                (head)->prev = (queue_entry_t)(elt);		\
-                ((type)prev)->field.next = (queue_entry_t)(elt);\
-        }							\
-} while(0)
-
-/*
- *	Macro:		queue_field [internal use only]
- *	Function:
- *		Find the queue_chain_t (or queue_t) for the
- *		given element (thing) in the given queue (head)
- */
-#define	queue_field(head, thing, type, field)			\
-                (((head) == (thing)) ? (head) : &((type)(thing))->field)
-
-/*
- *	Macro:		queue_remove
- *	Header:
- *		void queue_remove(q, qe, type, field)
- *			arguments as in queue_enter
- */
-#define	queue_remove(head, elt, type, field)			\
-do {							\
-        register queue_entry_t	next, prev;			\
-                                                                \
-        next = (elt)->field.next;				\
-        prev = (elt)->field.prev;				\
-                                                                \
-        queue_field((head), next, type, field)->prev = prev;	\
-        queue_field((head), prev, type, field)->next = next;	\
-} while(0)
-
-
-typedef struct _KEXTD {
-    CFIndex _refcount;
-    CFRunLoopRef _runloop;
-    CFRunLoopSourceRef _signalsource;
-    CFRunLoopSourceRef _kernelsource;
-    CFMutableArrayRef _scanPaths;
-    CFMutableArrayRef _unloaded;
-    CFMutableArrayRef _helpers;
-    queue_head_t _requestQ;
-    PTLockRef _runloop_lock;
-    PTLockRef _queue_lock;
-    KEXTManagerRef _manager;
-    mach_port_t _catPort;
-    Boolean _initializing;
-    Boolean _beVerbose;
-#if TIMERSOURCE
-    Boolean _pollFileSystem;
-    CFIndex _pollingPeriod;
-#endif
-} KEXTD;
-
-typedef struct _request {
-    unsigned int	type;
-    CFStringRef		kmodname;
-    CFStringRef		kmodvers;
-    queue_chain_t	link;
-} request_t;
-
-typedef struct _KEXTDHelper {
-    void * context;
-    KEXTDHelperCallbacks cbs;
-} KEXTDHelper;
-
-CFDictionaryRef   _KEXTPersonalityGetProperties(KEXTPersonalityRef personality);
-static void       _KEXTDRemovePersonalitiesFromUnloadedList(KEXTDRef kextd, CFStringRef parentKey);
-static void       _KEXTDAddPersonalitiesWithModuleToUnloadedList(KEXTDRef kextd, CFStringRef modName);
-const void *      _KEXTPersonalityRetainCB(CFAllocatorRef allocator, const void *ptr);
-void              _KEXTPersonalityReleaseCB(CFAllocatorRef allocator, const void *ptr);
-Boolean           _KEXTPersonalityEqualCB(const void *ptr1, const void *ptr2);
-mach_port_t       _KEXTManagerGetMachPort(KEXTManagerRef manager);
-
-extern kern_return_t
-kmod_control(host_t host,
-             kmod_t id,
-             kmod_control_flavor_t flavor,
-             kmod_args_t *data,
-             mach_msg_type_number_t *dataCount);
-
-extern KEXTReturn KERN2KEXTReturn(kern_return_t kr);
-
-static KEXTDRef _kextd = NULL;
-
-static void logErrorFunction(const char * string)
-{
-    syslog(LOG_ERR, string);
-    return;
-}
-
-static void logMessageFunction(const char * string)
-{
-    syslog(LOG_INFO, string);
-    return;
-}
-
-
-static void ArrayMergeFunc(const void * val, void * context)
-{
-    CFMutableArrayRef array;
-
-    array = context;
-
-    CFArrayAppendValue(array, val);
-}
-
-static void CFArrayMergeArray(CFMutableArrayRef array1, CFArrayRef array2)
-{
-    CFRange range;
-
-    if ( !array1 || !array2 ) {
-        return;
-    }
-
-    range = CFRangeMake(0, CFArrayGetCount(array2));
-    CFArrayApplyFunction(array2, range, ArrayMergeFunc, array1);
-}
-
-static void CallHelperEvent(void * val, void * context[])
-{
-    KEXTDRef kextd;
-    KEXTEvent event;
-    KEXTDHelper * helper;
-    CFTypeRef item;
-
-    helper = val;
-    kextd = context[0];
-    event = *(KEXTEvent *)context[1];
-    item = context[2];
-
-    if ( helper && context && helper->cbs.EventOccurred ) {
-        helper->cbs.EventOccurred(event, item, kextd);
-    }
-}
-
-static void ConfigsForBundles(const void * var, void * context[])
-{
-    KEXTManagerRef manager;
-    KEXTBundleRef bundle;
-    CFMutableArrayRef array;
-    CFArrayRef configs;
-
-    bundle = (KEXTBundleRef)var;
-
-    manager = context[0];
-    array = context[1];
-
-    configs = KEXTManagerCopyConfigsForBundle(manager, bundle);
-    if ( configs ) {
-        CFArrayMergeArray(array, configs);
-        CFRelease(configs);
-    }
-}
-
-
-static inline KEXTBootlevel _KEXTDGetBootlevel(KEXTPersonalityRef personality)
-{
-    KEXTBootlevel bootlevel;
-    CFStringRef priority;
-    CFStringRef category;
-
-    bootlevel = kKEXTBootlevelExempt;
-    priority = KEXTPersonalityGetProperty(personality, CFSTR("BootPriority"));
-    if ( !priority ) {
-        category = KEXTPersonalityGetProperty(personality, CFSTR("DeviceCategory"));
-        if ( !category ) {
-            return kKEXTBootlevelExempt;
-        }
-
-        if ( CFEqual(category, CFSTR("System Controller")) ) {
-             bootlevel = kKEXTBootlevelRequired;
-        }
-        else if ( CFEqual(category, CFSTR("Bus Controller")) ) {
-             bootlevel = kKEXTBootlevelFlexible;
-        }
-        else if ( CFEqual(category, CFSTR("Keyboard")) ) {
-             bootlevel = kKEXTBootlevelSingleUser;
-        }
-        else if ( CFEqual(category, CFSTR("Input Device")) ) {
-             bootlevel = kKEXTBootlevelExempt;
-        }
-        else if ( CFEqual(category, CFSTR("Pointing Device")) ) {
-             bootlevel = kKEXTBootlevelExempt;
-        }
-        else if ( CFEqual(category, CFSTR("Mouse")) ) {
-             bootlevel = kKEXTBootlevelRecovery;
-        }
-        else if ( CFEqual(category, CFSTR("Graphics Controller")) ) {
-             bootlevel = kKEXTBootlevelRecovery;
-        }
-        else if ( CFEqual(category, CFSTR("Graphics Accelerator")) ) {
-             bootlevel = kKEXTBootlevelExempt;
-        }
-        else if ( CFEqual(category, CFSTR("Video Device")) ) {
-             bootlevel = kKEXTBootlevelExempt;
-        }
-        else if ( CFEqual(category, CFSTR("Disk Controller")) ) {
-             bootlevel = kKEXTBootlevelFlexible;
-        }
-        else if ( CFEqual(category, CFSTR("Disk Media")) ) {
-             bootlevel = kKEXTBootlevelFlexible;
-        }
-        else if ( CFEqual(category, CFSTR("Audio Controller")) ) {
-             bootlevel = kKEXTBootlevelExempt;
-        }
-        else if ( CFEqual(category, CFSTR("Sound Device")) ) {
-             bootlevel = kKEXTBootlevelExempt;
-        }
-        else if ( CFEqual(category, CFSTR("Network Controller")) ) {
-             bootlevel = kKEXTBootlevelFlexible;
-        }
-
-        return bootlevel;
-    }
-
-    if ( CFEqual(priority, CFSTR("Exempt")) ) {
-        bootlevel = kKEXTBootlevelExempt;
-    }
-    else if ( CFEqual(priority, CFSTR("Recovery")) ) {
-        bootlevel = kKEXTBootlevelRecovery;
-    }
-    else if ( CFEqual(priority, CFSTR("Special")) ) {
-        bootlevel = kKEXTBootlevelSingleUser;
-    }
-    else if ( CFEqual(priority, CFSTR("Flexible")) ) {
-        bootlevel = kKEXTBootlevelFlexible;
-    }
-    else if ( CFEqual(priority, CFSTR("Required")) ) {
-        bootlevel = kKEXTBootlevelRequired;
-    }
-
-    return bootlevel;
-}
-
-static void ArrayAddToLoadList(void * val, void * context[])
-{
-    KEXTPersonalityRef person;
-    KEXTBootlevel bootlevel;
-    CFMutableArrayRef unloaded;
-    CFMutableArrayRef loadlist;
-    CFRange range;
-    Boolean doAdd;
-
-    if ( !val || !context ) {
-        return;
-    }
-
-    doAdd = true;
-    person = val;
-    unloaded = context[0];
-    loadlist = context[1];
-    bootlevel = *(KEXTBootlevel *)context[2];
-
-    if ( bootlevel != kKEXTBootlevelNormal ) {
-        doAdd  = _KEXTDGetBootlevel(person) & bootlevel;
-    }
-
-    if ( doAdd ) {
-        range = CFRangeMake(0, CFArrayGetCount(loadlist));
-        if ( !CFArrayContainsValue(loadlist, range, person) ) {
-            CFArrayAppendValue(loadlist, person);
-        }
-    }
-    else {
-        range = CFRangeMake(0, CFArrayGetCount(unloaded));
-        if ( !CFArrayContainsValue(unloaded, range, person) ) {
-            CFArrayAppendValue(unloaded, person);
-        }
-        CFArrayAppendValue(unloaded, person);
-    }
-}
-
-static void signalhandler(int signal)
-{
-    if ( _kextd && (signal == SIGHUP) ) {
-        KEXTDHangup(_kextd);
-    }
-}
-
-static KEXTReturn _KEXTDInitSyslog(KEXTD * k)
-{
-    openlog("kextd", LOG_PID | LOG_NDELAY, LOG_DAEMON);
-
-    return kKEXTReturnSuccess;
-}
-
-// This is called when authenticating a new bundle.
-static KEXTReturn _KEXTDAuthenticateBundleCB(CFURLRef url, void * context)
-{
-    Boolean ret;
-
-    ret = KEXTManagerAuthenticateURL(url);
-    if ( !ret ) {
-        KEXTD * k = (KEXTD *)context;
-        KEXTEvent event;
-        CFStringRef urlString;
-        CFRange range;
-        char name[256];
-        void * context2[3];
-
-        urlString = CFURLGetString(url);
-        if ( CFStringGetCString(urlString, name, 256, kCFStringEncodingNonLossyASCII) )
-            syslog(LOG_ERR, "%s failed authentication.", name);
-
-        event = kKEXTEventBundleAuthenticationFailed;
-        context2[0] = k;
-        context2[1] = &event;
-        context2[2] = (void *)url;
-
-        range = CFRangeMake(0, CFArrayGetCount(k->_helpers));
-        CFArrayApplyFunction(k->_helpers, range, (CFArrayApplierFunction)CallHelperEvent, context2);
-    }
-
-    return ret;
-}
-
-// This is called when a new bundle has been found.
-static Boolean _KEXTDWillAddBundleCB(KEXTManagerRef manager, KEXTBundleRef bundle, void * context)
-{
-    KEXTD * k = (KEXTD *)context;
-    CFURLRef url;
-    CFIndex count;
-    CFIndex i;
-    Boolean ret;
-
-    ret = true;
-    count = CFArrayGetCount(k->_helpers);
-    for ( i = 0; i < count; i++ ) {
-        KEXTDHelper * helper;
-
-        helper = (KEXTDHelper *)CFArrayGetValueAtIndex(k->_helpers, i);
-        if ( !helper )
-            continue;
-
-        if ( helper->cbs.BundleAdd ) {
-            ret = helper->cbs.BundleAdd(bundle, helper->context);
-            if ( !ret )
-                break;
-        }
-    }
-
-    url = KEXTBundleCopyURL(bundle);
-    if ( url ) {
-        if ( k->_beVerbose && ret ) {
-            CFStringRef cfstr;
-            char str[256];
-
-            cfstr = CFURLGetString(url);
-            if ( CFStringGetCString(cfstr, str, 256, kCFStringEncodingNonLossyASCII) ) {
-                syslog(LOG_INFO, "%s added.", str);
-            }
-        }
-
-        // Remove any unloaded personalities from look-aside queue
-        // which are in this bundle.
-        _KEXTDRemovePersonalitiesFromUnloadedList((KEXTDRef)k, KEXTBundleGetPrimaryKey(bundle));
-        CFRelease(url);
-    }
-
-    return ret;
-}
-
-// This is called after a bundle has been added to the KEXTManager database.
-static void _KEXTDWasAddedBundleCB(KEXTManagerRef manager, KEXTBundleRef bundle, void * context)
-{
-    KEXTD * k;
-    KEXTBootlevel bootlevel;
-    CFMutableArrayRef toload;
-    CFArrayRef persons;
-    CFArrayRef configs;
-    CFArrayRef unloaded;
-    CFRange range;
-    void * context2[3];
-
-    k = (KEXTD *)context;
-    if ( k->_initializing ) {
-        return;
-    }
-
-    bootlevel = kKEXTBootlevelNormal;
-
-    toload = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-    if ( !toload ) {
-        return;
-    }
-
-    context2[0] = k->_unloaded;
-    context2[1] = toload;
-    context2[2] = &bootlevel;
-
-
-    // Create a list of all personalities and configurations
-    // and send it to the catalogue.  First, get the unloaded
-    // personalities.
-    unloaded = CFArrayCreateCopy(kCFAllocatorDefault, k->_unloaded);
-    CFArrayRemoveAllValues(k->_unloaded);
-    if ( unloaded ) {
-        range = CFRangeMake(0, CFArrayGetCount(unloaded));
-        CFArrayApplyFunction(unloaded, range, (CFArrayApplierFunction)ArrayAddToLoadList, context2);
-        CFRelease(unloaded);
-    }
-
-    persons = KEXTManagerCopyPersonalitiesForBundle(manager, bundle);
-    if ( persons ) {
-        range = CFRangeMake(0, CFArrayGetCount(persons));
-        CFArrayApplyFunction(persons, range, (CFArrayApplierFunction)ArrayAddToLoadList, context2);
-        CFRelease(persons);
-    }
-
-    configs = KEXTManagerCopyConfigsForBundle(manager, bundle);
-    if ( configs ) {
-        range = CFRangeMake(0, CFArrayGetCount(configs));
-        CFArrayApplyFunction(configs, range, (CFArrayApplierFunction)ArrayAddToLoadList, context2);
-        CFRelease(configs);
-        
-    }
-
-    // Send the list to IOCatalogue.
-    if ( CFArrayGetCount(toload) > 0 ) {
-        KEXTManagerLoadPersonalities(k->_manager, toload);
-    }
-    
-    CFRelease(toload);
-}
-
-static void _KEXTDConfigWasAdded(KEXTManagerRef manager, KEXTConfigRef config, void * context)
-{
-    KEXTD * kextd;
-
-    if ( !manager || !config || !context ) {
-        return;
-    }
-
-    kextd = context;
-
-    if ( !kextd->_initializing ) {
-        CFStringRef primaryKey;
-        CFArrayRef array;
-        void * vals[1];
-
-        primaryKey = CFDictionaryGetValue(config, CFSTR("ParentKey"));
-        if ( !primaryKey ) {
-            return;
-        }
-
-        if ( !KEXTManagerGetBundle(manager, primaryKey) ) {
-            return;
-        }
-        
-        vals[0] = config;
-        array = CFArrayCreate(kCFAllocatorDefault, vals, 1, &kCFTypeArrayCallBacks);
-        if ( array ) {
-            KEXTManagerLoadPersonalities(manager, array);
-            CFRelease(array);
-        }
-    }
-}
-
-static void _KEXTDConfigWasRemoved(KEXTManagerRef manager, KEXTConfigRef config, void * context)
-{
-    KEXTD * kextd;
-    
-    if ( !manager || !config || !context ) {
-        return;
-    }
-
-    kextd = context;
-    
-    if ( !kextd->_initializing ) {
-        KEXTManagerUnloadPersonality(manager, config);
-    }
-}
-
-static void ArrayUnloadPersonality(const void * val, void * context)
-{
-    KEXTManagerRef manager;
-    KEXTPersonalityRef person;
-
-    manager = context;
-    person = (KEXTPersonalityRef)val;
-    
-    KEXTManagerUnloadPersonality(manager, person);
-}
-
-// This is called when a bundle has been removed from the filesystem.
-static Boolean _KEXTDWillRemoveBundleCB(KEXTManagerRef manager, KEXTBundleRef bundle, void * context)
-{
-    KEXTD * k = (KEXTD *)context;
-    CFIndex count;
-    CFIndex i;
-    Boolean ret;
-
-    ret = true;
-    count = CFArrayGetCount(k->_helpers);
-    for ( i = 0; i < count; i++ ) {
-        KEXTDHelper * helper;
-
-        helper = (KEXTDHelper *)CFArrayGetValueAtIndex(k->_helpers, i);
-        if ( !helper )
-            continue;
-
-        if ( helper->cbs.BundleRemove ) {
-            ret = helper->cbs.BundleRemove(bundle, helper->context);
-            if ( !ret )
-                break;
-        }
-    }
-    
-    if ( ret ) {
-        CFArrayRef personalities;
-        CFArrayRef configs;
-        CFURLRef url;
-        CFRange range;
-
-        // XXX -- svail: might want to unload bundle personalities
-        // from IOCatalogue and maybe unload the modules if possible.
-        // If a module is present with active personalities, don't remove
-        // bundle from database.
-        personalities = KEXTManagerCopyPersonalitiesForBundle(manager, bundle);
-        if ( personalities ) {
-            range = CFRangeMake(0, CFArrayGetCount(personalities));
-            CFArrayApplyFunction(personalities, range, ArrayUnloadPersonality, manager);
-            CFRelease(personalities);
-        }
-        
-        configs = KEXTManagerCopyConfigsForBundle(manager, bundle);
-        if ( configs ) {
-            range = CFRangeMake(0, CFArrayGetCount(configs));
-            CFArrayApplyFunction(configs, range, ArrayUnloadPersonality, manager);
-            CFRelease(configs);
-        }
-        
-        url = KEXTBundleCopyURL(bundle);
-        if ( url ) {
-            if ( k->_beVerbose && ret ) {
-                CFStringRef cfstr;
-                char str[256];
-
-                cfstr = CFURLGetString(url);
-                if ( CFStringGetCString(cfstr, str, 256, kCFStringEncodingNonLossyASCII) ) {
-                    syslog(LOG_INFO, "%s removed.", str);
-                }
-            }
-
-            // Remove any unloaded personalities from the unloaded
-            // list if they are associated with the bundle.
-
-            _KEXTDRemovePersonalitiesFromUnloadedList((KEXTDRef)k, KEXTBundleGetPrimaryKey(bundle));
-            CFRelease(url);
-        }
-    }
-    
-    return ret;
-}
-
-// This is called before KEXT loads a KMOD.
-static Boolean _KEXTDModuleWillLoadCB(KEXTManagerRef manager, KEXTModuleRef module, void * context)
-{
-    KEXTD * k;
-    CFIndex count;
-    CFIndex i;
-    Boolean ret;
-
-    k = (KEXTD *)context;
-
-    ret = true;
-    count = CFArrayGetCount(k->_helpers);
-    for ( i = 0; i < count; i++ ) {
-        KEXTDHelper * helper;
-
-        helper = (KEXTDHelper *)CFArrayGetValueAtIndex(k->_helpers, i);
-        if ( !helper )
-            continue;
-
-        if ( helper->cbs.ModuleWillLoad ) {
-            if ( !helper->cbs.ModuleWillLoad(module, helper->context) ) {
-                ret = false;
-                break;
-            }
-        }
-    }
-
-    if ( ret ) {
-        CFStringRef moduleName;
-        char name[256];
-
-        moduleName = KEXTModuleGetProperty(module, CFSTR("CFBundleIdentifier"));
-        if ( !moduleName )
-            return false;
-
-        if ( !CFStringGetCString(moduleName, name, 256, kCFStringEncodingNonLossyASCII) )
-            return false;
-
-        syslog(LOG_INFO, "loading module: %s.\n", name);
-    }
-
-    return ret;
-}
-
-// This is called when a module has been successfully loaded.
-static void _KEXTDModuleWasLoadedCB(KEXTManagerRef manager, KEXTModuleRef module, void * context)
-{
-    KEXTD * k;
-    CFArrayRef array;
-    CFMutableArrayRef send;
-    CFIndex count;
-    CFIndex i;
-
-    k = (KEXTD *)context;
-
-    count = CFArrayGetCount(k->_helpers);
-    for ( i = 0; i < count; i++ ) {
-        KEXTDHelper * helper;
-
-        helper = (KEXTDHelper *)CFArrayGetValueAtIndex(k->_helpers, i);
-        if ( !helper )
-            continue;
-
-        if ( helper->cbs.ModuleWasLoaded ) {
-            helper->cbs.ModuleWasLoaded(module, helper->context);
-        }
-    }
-
-    // Remove personalities from unloaded list if they
-    // are associated with the module and pass them to the
-    // kernel just in case they aren't there yet.
-
-    array = CFArrayCreateCopy(kCFAllocatorDefault, k->_unloaded);
-    send = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-    count = CFArrayGetCount(array);
-    
-    CFArrayRemoveAllValues(k->_unloaded);
-
-    for ( i = 0; i < count; i++ ) {
-        KEXTPersonalityRef person;
-        CFStringRef moduleID;
-        CFStringRef personalityBundleID;
-
-        person = (KEXTPersonalityRef)CFArrayGetValueAtIndex(array, i);
-        if ( !person ) {
-            continue;
-        }
-        
-        moduleID = KEXTPersonalityGetProperty(person, CFSTR("CFBundleIdentifier"));
-        if ( !moduleID ) {
-            continue;
-        }
-
-        personalityBundleID = KEXTModuleGetProperty(module, CFSTR("CFBundleIdentifier"));
-        if ( !personalityBundleID ) {
-            continue;
-        }
-
-        if ( !CFEqual(moduleID, personalityBundleID) ) {
-            CFArrayAppendValue(k->_unloaded, person);
-        }
-        else {
-            CFArrayAppendValue(send, person);
-        }
-    }
-
-    if ( CFArrayGetCount(send) > 0 ) {
-        KEXTManagerLoadPersonalities(k->_manager, send);
-    }
-    
-    CFRelease(send);
-    CFRelease(array);
-    
-    if ( k->_beVerbose ) {
-        CFStringRef moduleName;
-        char name[256];
-
-        moduleName = KEXTModuleGetProperty(module, CFSTR("CFBundleIdentifier"));
-        if ( !moduleName )
-            return;
-
-        if ( !CFStringGetCString(moduleName, name, 256, kCFStringEncodingNonLossyASCII) )
-            return;
-        
-        syslog(LOG_INFO, "loaded module: %s\n", name);
-    }
-}
-
-static KEXTReturn _KEXTDModuleErrorCB(KEXTManagerRef manager, KEXTModuleRef module, KEXTReturn error, void * context)
-{
-    char name[256];
-    KEXTD * k;
-    KEXTReturn ret;
-    CFIndex i;
-    CFIndex count;
-    CFStringRef moduleName;
-
-    k = (KEXTD *)context;
-
-    moduleName = KEXTModuleGetProperty(module, CFSTR("CFBundleIdentifier"));
-    if ( !moduleName )
-        return kKEXTReturnPropertyNotFound;
-
-    if ( !CFStringGetCString(moduleName, name, 256, kCFStringEncodingNonLossyASCII) )
-        return kKEXTReturnNoMemory;
-
-    if ( error == kKEXTReturnModuleAlreadyLoaded ) {
-        if ( k->_beVerbose )
-            syslog(LOG_INFO, "module already loaded: %s.\n", name);
-
-        return error;
-    }
-
-    ret = error;
-    count = CFArrayGetCount(k->_helpers);
-    for ( i = 0; i < count; i++ ) {
-        KEXTDHelper * helper;
-
-        helper = (KEXTDHelper *)CFArrayGetValueAtIndex(k->_helpers, i);
-        if ( !helper )
-            continue;
-
-        if ( helper->cbs.ModuleLoadError ) {
-            ret = helper->cbs.ModuleLoadError(module, error, helper->context);
-            if ( ret == kKEXTReturnSuccess ) {
-                break;
-            }
-        }
-    }
-    if ( ret == kKEXTReturnSuccess )
-        return kKEXTReturnSuccess;
-
-    syslog(LOG_ERR, "error (%d) loading module: %s.\n", ret, name);
-
-    return ret;
-}
-
-#if TIMERSOURCE
-static void _KEXTDTimerCallout(CFRunLoopTimerRef timer, void * info)
-{
-    KEXTDScanPaths((KEXTDRef)info, false);
-}
-#endif
-
-static void _KEXTDSIGHUPCallout(void * info)
-{
-    KEXTD * k;
-
-    k = (KEXTD *)info;
-    if ( k->_beVerbose ) {
-        syslog(LOG_INFO, "user requests directory re-scan.");
-    }
-
-    // Check for new or removed bundles and do the appropriate
-    // things.
-    KEXTDScanPaths((KEXTDRef)info, false);
-
-    // Make sure we try to load the unloaded personalities
-    // It's probably overkill to do this here.
-    if ( CFArrayGetCount(k->_unloaded) > 0 ) {
-        KEXTManagerLoadPersonalities(k->_manager, k->_unloaded);
-    }
-}
-
-// This function is called when IOCatalogue requests a driver module.
-static void _KEXTDPerform(void * info)
-{
-    KEXTD * k;
-    unsigned int type;
-
-    k = (KEXTD *)info;
-
-//    KEXTDScanPaths((KEXTDRef)k, false);
-
-    PTLockTakeLock(k->_queue_lock);
-    while ( !queue_empty(&k->_requestQ) ) {
-        request_t * reqstruct;
-        CFStringRef name;
-
-        // Dequeue the kernel request structure.
-        reqstruct = (request_t *)queue_first(&k->_requestQ);
-        queue_remove(&k->_requestQ, reqstruct, request_t *, link);
-        PTLockUnlock(k->_queue_lock);
-
-        type = reqstruct->type;
-        name = reqstruct->kmodname;
-        free(reqstruct);
-
-        if ( name ) {
-
-            if ( k->_beVerbose ) {
-                char modname[256];
-
-                if ( CFStringGetCString(name, modname, 256, kCFStringEncodingNonLossyASCII) ) {
-                    syslog(LOG_INFO, "kernel requests module: %s", modname);
-                }
-            }
-
-            KEXTDKernelRequest((KEXTDRef)k, name);
-            CFRelease(name);
-        }
-
-        PTLockTakeLock(k->_queue_lock);
-    }
-    PTLockUnlock(k->_queue_lock);
-}
-
-KEXTDRef KEXTDCreate(CFArrayRef scanPaths, KEXTReturn * error)
-{
-    KEXTD * kextd;
-
-    kextd = (KEXTD *)malloc(sizeof(KEXTD));
-    if ( !kextd ) {
-        *error = kKEXTReturnNoMemory;
-        return NULL;
-    }
-    memset(kextd, 0, sizeof(KEXTD));
-
-    kextd->_queue_lock = PTLockCreate();
-    kextd->_runloop_lock = PTLockCreate();
-
-    kextd->_helpers = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
-    kextd->_unloaded = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-    kextd->_scanPaths = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-    if ( !kextd->_scanPaths || !kextd->_unloaded || !kextd->_helpers ) {
-        *error = kKEXTReturnNoMemory;
-        KEXTDFree((KEXTDRef)kextd);
-        return NULL;
-    }
-
-    kextd->_initializing = true;
-    kextd->_beVerbose = false;
-#if TIMERSOURCE
-    kextd->_pollFileSystem = false;
-    kextd->_pollingPeriod = TIMER_PERIOD_S;
-#endif
-
-    queue_init(&kextd->_requestQ);
-    
-    if ( scanPaths ) {
-        CFURLRef url;
-        CFIndex count;
-        CFIndex i;
-
-        count = CFArrayGetCount(scanPaths);
-        for ( i = 0; i < count; i++ ) {
-            url = (CFURLRef)CFArrayGetValueAtIndex(scanPaths, i);
-            KEXTDAddScanPath((KEXTDRef)kextd, url);
-        }
-    }
-
-    return (KEXTDRef)kextd;
-}
-
-static void _KEXTDFlushHelpers(KEXTDRef kextd)
-{
-    KEXTD * k;
-    CFIndex count;
-    CFIndex i;
-
-    k = (KEXTD *)kextd;
-    count = CFArrayGetCount(k->_helpers);
-    for ( i = 0; i < count; i++ ) {
-        KEXTDHelper * helper;
-
-        helper = (KEXTDHelper *)CFArrayGetValueAtIndex(k->_helpers, i);
-        if ( !helper )
-            continue;
-
-        if ( helper->cbs.DaemonWillTerminate )
-            helper->cbs.DaemonWillTerminate(helper->context);
-        if ( helper->cbs.HelperFinalize )
-            helper->cbs.HelperFinalize(helper->context);
-
-        free(helper);
-    }
-}
-
-void KEXTDFree(KEXTDRef kextd)
-{
-    KEXTD * k;
-
-    k = (KEXTD *)kextd;
-
-    syslog(LOG_DEBUG, "terminating.");
-
-    if ( k->_helpers ) {
-        _KEXTDFlushHelpers(kextd);
-        CFRelease(k->_helpers);
-    }
-    if ( k->_kernelsource )
-        CFRelease(k->_kernelsource);
-    if ( k->_signalsource )
-        CFRelease(k->_signalsource);
-    if ( k->_runloop )  
-        CFRelease(k->_runloop);
-    if ( k->_scanPaths )
-        CFRelease(k->_scanPaths);
-    if ( k->_manager )
-        KEXTManagerRelease(k->_manager);
-    if ( k->_queue_lock )
-        PTLockFree(k->_queue_lock);
-    if ( k->_runloop_lock )
-        PTLockFree(k->_runloop_lock);
-    
-    closelog();
-
-    free(kextd);
-}
-
-void KEXTDReset(KEXTDRef kextd)
-{
-    KEXTD * k;
-    CFIndex count;
-    CFIndex i;
-
-    syslog(LOG_DEBUG, "resetting.");
-    
-    k = (KEXTD *)kextd;
-    count = CFArrayGetCount(k->_helpers);
-    for ( i = 0; i < count; i++ ) {
-        KEXTDHelper * helper;
-
-        helper = (KEXTDHelper *)CFArrayGetValueAtIndex(k->_helpers, i);
-        if ( !helper )
-            continue;
-
-        if ( helper->cbs.EventOccurred )
-            helper->cbs.EventOccurred(kKEXTEventReset, NULL, helper->context);
-    }
-
-    if ( k->_manager )
-        KEXTManagerReset(k->_manager);
-    
-    KEXTDScanPaths(kextd, false);
-}
-
-static KEXTReturn _KEXTDSendDataToCatalog(KEXTDRef kextd, int flag, CFTypeRef obj)
-{
-    KEXTD * k;
-    KEXTReturn error;
-    CFDataRef data;
-    CFIndex len;
-    void * ptr;
-
-    k = (KEXTD *)kextd;
-    data = NULL;
-    error = kKEXTReturnSuccess;
-
-    data = IOCFSerialize(obj, 0);
-    if ( !data ) {
-        return kKEXTReturnSerializationError;
-    }
-
-    len = CFDataGetLength(data);
-    ptr = (void *)CFDataGetBytePtr(data);
-    error = KERN2KEXTReturn(IOCatalogueSendData(k->_catPort, flag, ptr, len));
-    CFRelease(data);
-
-    return error;
-}
-
-static KEXTReturn _KEXTDSendPersonalities(KEXTDRef kextd, KEXTBootlevel bootlevel)
-{
-    KEXTReturn error;
-    CFArrayRef persons;
-    CFArrayRef bundles;
-    CFMutableArrayRef configs;
-    CFMutableArrayRef toload;
-    CFRange range;
-    void * context[3];
-
-    error = kKEXTReturnSuccess;
-
-    toload = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-    if ( !toload ) {
-        return kKEXTReturnNoMemory;
-    }
-
-    configs = NULL;
-    bundles = KEXTManagerCopyAllBundles(((KEXTD*)kextd)->_manager);
-    if ( bundles ) {
-        configs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-        if ( !configs ) {
-            CFRelease(bundles);
-            CFRelease(toload);
-            return kKEXTReturnNoMemory;
-        }
-
-        context[0] = ((KEXTD*)kextd)->_manager;
-        context[1] = configs;
-
-        range = CFRangeMake(0, CFArrayGetCount(bundles));
-        CFArrayApplyFunction(bundles, range, (CFArrayApplierFunction)ConfigsForBundles, context);
-        CFRelease(bundles);
-    }
-    
-    // Filter out any inappropriate personalities given the bootlevel of the 
-    // system. Store these personalities in the _unloaded list, they will be
-    // loaded when a SIGHUP is sent to the daemon.
-    context[0] = ((KEXTD *)kextd)->_unloaded;
-    context[1] = toload;
-    context[2] = &bootlevel;
-
-    persons = KEXTManagerCopyAllPersonalities(((KEXTD*)kextd)->_manager);
-    if ( persons ) {
-        range = CFRangeMake(0, CFArrayGetCount(persons));
-        CFArrayApplyFunction(persons, range, (CFArrayApplierFunction)ArrayAddToLoadList, context);
-        CFRelease(persons);
-    }
-
-    if ( configs ) {
-        range = CFRangeMake(0, CFArrayGetCount(configs));
-        CFArrayApplyFunction(configs, range, (CFArrayApplierFunction)ArrayAddToLoadList, context);
-        CFRelease(configs);
-    }
-
-    if ( CFArrayGetCount(toload) > 0 ) {
-        error = KEXTManagerLoadPersonalities(((KEXTD *)kextd)->_manager, toload);
-    }
-
-    KEXTdaemonSignal();
-
-    CFRelease(toload);
-
-    return error;
-
-}
-
-static inline Boolean _KEXTPersonalityNeedsModule(KEXTPersonalityRef person, CFStringRef modName)
-{
-    CFStringRef name;
-
-    name = KEXTPersonalityGetProperty(person, CFSTR("CFBundleIdentifier"));
-    if ( !name ) {
-        return false;
-    }
-
-    return CFEqual(name, modName);
-}
-
-// If a module fails to load for some reason, then put the
-// personalities associated with this module in a look-aside
-// buffer, we'll try loading them later, maybe when a broken
-// dependency is fixed.
-static void _KEXTDAddPersonalitiesWithModuleToUnloadedList(KEXTDRef kextd, CFStringRef modName)
-{
-    CFArrayRef array;
-    CFIndex i;
-    CFIndex count;
-    KEXTD * k;
-
-    if ( !modName )
-        return;
-
-    k = (KEXTD *)kextd;
-
-    array = KEXTManagerCopyAllEntities(k->_manager);
-    if ( !array )
-        return;
-    
-    // Find personalities which depend on this module.
-    count = CFArrayGetCount(array);
-    for ( i = 0; i < count; i++ ) {
-        CFStringRef type;
-        CFStringRef name;
-        CFRange range;
-        KEXTEntityRef entity;
-
-        entity = (KEXTEntityRef)CFArrayGetValueAtIndex(array, i);
-        if ( !entity )
-            continue;
-
-        type = KEXTManagerGetEntityType(entity);
-        if ( !type || !CFEqual(type, KEXTPersonalityGetEntityType()) ) {
-            continue;
-        }
-
-        name = KEXTPersonalityGetProperty(entity, CFSTR("CFBundleIdentifier"));
-        if ( !name || !CFEqual(modName, name) ) {
-            continue;
-        }
-
-        range = CFRangeMake(0, CFArrayGetCount(k->_unloaded));
-
-        if ( CFArrayContainsValue(k->_unloaded, range, entity) ) {
-            continue;
-        }
-
-        CFArrayAppendValue(k->_unloaded, entity);
-
-        if ( !k->_initializing ) {
-            KEXTManagerUnloadPersonality(k->_manager, entity);
-        }
-
-    }
-    CFRelease(array);
-}
-
-static void RemovePersonsWithParentFromUnloadedList(void * val, void * context[])
-{
-    KEXTPersonalityRef person;
-    CFMutableArrayRef unloaded;
-    CFStringRef parentKey;
-    CFStringRef key;
-
-    if ( !val || !context ) {
-        return;
-    }
-    
-    person = val;
-    unloaded = context[0];
-    parentKey = context[1];
-
-    key = CFDictionaryGetValue(person, CFSTR("ParentKey"));
-    if ( !parentKey || !key || CFEqual(parentKey, key) ) {
-        return;
-    }
-
-    CFArrayAppendValue(unloaded, person);
-}
-
-// Remove personalities from the unloaded list if their
-// associated bundle is removed.
-static void _KEXTDRemovePersonalitiesFromUnloadedList(KEXTDRef kextd, CFStringRef parentKey)
-{
-    CFMutableArrayRef unloaded;
-    CFArrayRef array;
-    CFRange range;
-    void * context[2];
-    
-    unloaded = ((KEXTD *)kextd)->_unloaded;
-    
-    array = CFArrayCreateCopy(kCFAllocatorDefault, unloaded);
-    CFArrayRemoveAllValues(unloaded);
-
-    context[0] = unloaded;
-    context[1] = (void *)parentKey;
-    
-    range = CFRangeMake(0, CFArrayGetCount(array));
-    CFArrayApplyFunction(
-                    array,
-                    range,
-                    (CFArrayApplierFunction)RemovePersonsWithParentFromUnloadedList,
-                    context);
-    
-    CFRelease(array);
-}
-
-static KEXTReturn _KEXTDProcessLoadCommand(KEXTDRef kextd, CFStringRef name)
-{
-    char cname[256];
-    KEXTReturn error;
-    KEXTD * k;
-
-    k = (KEXTD *)kextd;
-    if ( !CFStringGetCString(name, cname, 256, kCFStringEncodingNonLossyASCII) ) {
-        error = kKEXTReturnNoMemory;
-        return error;
-    }
-    
-    error = KEXTDLoadModule(kextd, name);
-    if ( error != kKEXTReturnSuccess &&
-         error != kKEXTReturnModuleAlreadyLoaded ) {
-        CFDictionaryRef matchingDict;
-        const void * keys[1];
-        const void * vals[1];
-
-        do {
-            keys[0] = CFSTR("CFBundleIdentifier");
-            vals[0] = name;
-
-            if ( !vals[0] ) {
-                error = kKEXTReturnPropertyNotFound;
-                break;
-            }
-
-            matchingDict = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-            if ( !matchingDict ) {
-                error = kKEXTReturnNoMemory;
-                break;
-            }
-
-            error = _KEXTDSendDataToCatalog(kextd, kIOCatalogRemoveDrivers, matchingDict);
-            CFRelease(matchingDict);
-            if ( error != kKEXTReturnSuccess ) {
-                syslog(LOG_DEBUG, "error ( %d) removing drivers.", error);
-                break;
-            }
-        } while ( false );
-
-        // Place personalities which failed to load this module onto
-        // a look-aside queue.  We'll try to load the module later
-        // when a broken dependency is fixed.
-        _KEXTDAddPersonalitiesWithModuleToUnloadedList(kextd, name);
-    }
-    else {
-
-        error = KERN2KEXTReturn(IOCatalogueModuleLoaded(k->_catPort, cname));
-        if ( error != kKEXTReturnSuccess ) {
-            syslog(LOG_DEBUG, "error (%d) signalling IOCatalogue.", error);
-        }
-    }
-    
-    return error;
-}
-
-void KEXTDHangup(KEXTDRef kextd)
-{
-    KEXTD * k;
-
-    k = (KEXTD *)kextd;
-    if ( k->_signalsource ) {
-        PTLockTakeLock(k->_runloop_lock);
-        CFRunLoopSourceSignal(k->_signalsource);
-        CFRunLoopWakeUp(k->_runloop);
-        PTLockUnlock(k->_runloop_lock);
-    }
-}
-
-KEXTReturn KEXTDKernelRequest(KEXTDRef kextd, CFStringRef name)
-{
-    KEXTD * k;
-    KEXTReturn ret;
-    
-    k = (KEXTD *)kextd;
-    ret = kKEXTReturnBadArgument;
-    if ( name ) {
-        KEXTEvent event;
-        CFRange range;
-        void * context[3];
-
-        event = kKEXTEventModuleRequest;
-
-        context[0] = kextd;
-        context[1] = &event;
-        context[2] = (void *)name;
-
-        range = CFRangeMake(0, CFArrayGetCount(k->_helpers));
-        CFArrayApplyFunction(k->_helpers, range, (CFArrayApplierFunction)CallHelperEvent, context);
-        ret = _KEXTDProcessLoadCommand((KEXTDRef)k, name);
-    }
-
-    return ret;
-}
-
-// The kernel blocks the thread which entered this
-// function until the kernel requests a driver to load.
-static void * _KEXTDKmodWait(void * info)
-{
-    mach_port_t kmodPort;
-    KEXTD * kextd;
-    KEXTReturn error;
-    request_t * reqstruct;
-    CFStringRef str;
-    unsigned int type;
-
-    if ( !info )
-        return (void *)kKEXTReturnBadArgument;
-
-    kmodPort = mach_host_self(); /* must be privileged to work */
-
-    kextd = (KEXTD *)info;
-    if ( !kextd->_kernelsource )
-        return (void *)kKEXTReturnBadArgument;
-
-    while ( 1 ) {
-        kmod_args_t data;
-        kmod_load_extension_cmd_t * cmd;
-        mach_msg_type_number_t dataCount;
-        kern_return_t kr;
-
-        data = 0;
-        dataCount = 0;
-        error = kKEXTReturnSuccess;
-
-        // Wait for kernel to unblock the thread.
-        kr = kmod_control(kmodPort, 0, KMOD_CNTL_GET_CMD, &data, &dataCount);
-        if ( kr != KERN_SUCCESS ) {
-            syslog(LOG_ERR, "error (%d): kmod_control.\n", kr);
-            continue;
-        }
-
-        cmd = (kmod_load_extension_cmd_t *)data;
-	type = cmd->type;
-	str = 0;
-
-        switch ( type ) {
-
-            case kIOCatalogMatchIdle: 
-		break;
-
-            case KMOD_LOAD_EXTENSION_PACKET: {
-                    
-                    str = CFStringCreateWithCString(NULL, cmd->name, kCFStringEncodingNonLossyASCII);
-		    if( str)
-			break;
-		    // else fall thru
-                }
-            default:
-                error = kKEXTReturnError;
-                break;
-        }
-
-	if( error == kKEXTReturnSuccess) {
-
-            reqstruct = (request_t *)malloc(sizeof(request_t));
-            if( reqstruct) {
-                memset(reqstruct, 0, sizeof(request_t));
-                reqstruct->type = cmd->type;
-                reqstruct->kmodname = str;
-                // queue up a reqest.
-                PTLockTakeLock(kextd->_queue_lock);
-                queue_enter(&kextd->_requestQ, reqstruct, request_t *, link);
-                PTLockUnlock(kextd->_queue_lock);
-
-                // wake up the runloop.
-                PTLockTakeLock(kextd->_runloop_lock);
-                CFRunLoopSourceSignal(kextd->_kernelsource);
-                CFRunLoopWakeUp(kextd->_runloop);
-                PTLockUnlock(kextd->_runloop_lock);
-            }
-	}
-
-        // Deallocate kernel allocated memory.
-        vm_deallocate(mach_task_self(), (vm_address_t)data, dataCount);
-        if ( kr != KERN_SUCCESS ) {
-            syslog(LOG_DEBUG, "vm_deallocate failed. aborting.\n");
-            exit(1);
-        }
-    }
-    
-    return (void *)kKEXTReturnSuccess;
-}
-
-
-#include <fcntl.h>
-#include <paths.h>
-#include <unistd.h>
-#include <assert.h>
-#include <mach/semaphore.h>
-#include <mach/sync_policy.h>
-#include <mach/bootstrap.h>	/* bootstrap_ports */
-#undef _bootstrap_user_		/* XXX FIXME */
-#include <servers/bootstrap.h>	/* bootstrap_look_up */
-#include <servers/bootstrap_defs.h>
-
-static void
-KEXTdaemonSignal(void)
-{
-    kern_return_t	kr;
-    mach_port_t		bs_port;
-    semaphore_t		sema;
-    static boolean_t	signalled = false;
-
-    if (signalled)
-	return;
-    signalled = TRUE;
-    if (gDebug) {
-        printf("kextd: signal\n");
-	return;
-    }
-
-    kr = task_get_bootstrap_port(mach_task_self(), &bs_port);
-    if( kr != KERN_SUCCESS )
-        syslog(LOG_ERR, "task_get_bootstrap_port (%lx)\n", kr);
-    kr = bootstrap_look_up(bs_port, "kextdsignal", &sema);
-    if( kr != BOOTSTRAP_SUCCESS )
-        syslog(LOG_ERR, "bootstrap_look_up(%lx)\n", kr);
-    kr = semaphore_signal_all( sema );
-    if( kr != KERN_SUCCESS )
-        syslog(LOG_ERR, "semaphore_signal_all(%lx)\n", kr);
-
-}
-
-static semaphore_t gDaemonSema;
-
-static void
-KEXTdaemonWait(void)
-{
-    kern_return_t	kr;
-    mach_port_t		masterPort;
-    mach_timespec_t 	waitTime = { 40, 0 };
-
-    kr = semaphore_timedwait( gDaemonSema, waitTime );
-    if( kr != KERN_SUCCESS )
-        syslog(LOG_ERR, "semaphore_timedwait(%lx)\n", kr);
-
-    IOMasterPort( MACH_PORT_NULL, &masterPort );
-    IOKitWaitQuiet( masterPort, &waitTime );
-    if( kr != KERN_SUCCESS )
-        syslog(LOG_ERR, "IOKitWaitQuiet(%lx)\n", kr);
-}
-
-static int
-KEXTdaemon(nochdir, noclose)
-	int nochdir, noclose;
-{
-    kern_return_t	kr;
-    mach_port_t		bs_port;
-    int fd;
-
-    kr = semaphore_create( mach_task_self(), &gDaemonSema, SYNC_POLICY_FIFO, 0);
-    if( kr != KERN_SUCCESS )
-        syslog(LOG_ERR, "semaphore_create(%lx)\n", kr);
-    kr = task_get_bootstrap_port(mach_task_self(), &bs_port);
-    if( kr != KERN_SUCCESS )
-        syslog(LOG_ERR, "task_get_bootstrap_port(%lx)\n", kr);
-    kr = bootstrap_register(bs_port, "kextdsignal", gDaemonSema);
-    if( kr != BOOTSTRAP_SUCCESS )
-        syslog(LOG_ERR, "bootstrap_look_up(%lx)\n", kr);
-
-    switch (fork()) {
-    case -1:
-            return (-1);
-    case 0:
-           /*
-            * Under some circumstances a CFRunLoop could have been established
-            * in the parent process.  Since the mach ports associated with the
-            * run loop are not passed to the child process we need to start
-            * with a clean slate.
-            */
-            _CFRunLoopSetCurrent(NULL);
-
-            break;
-    default:
-            KEXTdaemonWait();
-            _exit(0);
-    }
-
-    if (setsid() == -1)
-            return (-1);
-
-    if (!nochdir)
-            (void)chdir("/");
-
-    if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
-            (void)dup2(fd, STDIN_FILENO);
-            (void)dup2(fd, STDOUT_FILENO);
-            (void)dup2(fd, STDERR_FILENO);
-            if (fd > 2)
-                    (void)close (fd);
-    }
-    return (0);
-}
-
-
-#if TIMERSOURCE
-KEXTReturn KEXTDStartMain(KEXTDRef kextd, Boolean beVerbose, Boolean safeBoot, Boolean debug, Boolean poll, CFIndex period, KEXTBootlevel bootlevel, Boolean cdMKextBoot)
-#else
-KEXTReturn KEXTDStartMain(KEXTDRef kextd, Boolean beVerbose, Boolean safeBoot, Boolean debug, KEXTBootlevel bootlevel, Boolean cdMKextBoot)
-#endif
-{
-    pthread_attr_t kmod_thread_attr;
-    pthread_t kmod_thread;
-    KEXTReturn error;
-    KEXTD * k;
-    CFIndex count;
-    CFIndex i;
-    CFRunLoopSourceContext sourceContext;
-    KEXTManagerBundleLoadingCallbacks bcb = {
-        0,
-        _KEXTDAuthenticateBundleCB,
-        _KEXTDWillAddBundleCB,
-        _KEXTDWasAddedBundleCB,
-        NULL,
-        _KEXTDWillRemoveBundleCB,
-        NULL,
-    };
-    KEXTManagerModuleLoadingCallbacks modcbs = {
-        0,
-        _KEXTDModuleWillLoadCB,
-        _KEXTDModuleWasLoadedCB,
-        _KEXTDModuleErrorCB,
-        NULL,
-        NULL,
-    };
-    KEXTManagerConfigsCallbacks cfgcbs = {
-        0,
-        NULL,
-        _KEXTDConfigWasAdded,
-        NULL,
-        _KEXTDConfigWasRemoved,
-    };
-
-    gDebug = debug;
-    if (!debug && !cdMKextBoot) {
-        errno = 0;
-        KEXTdaemon(0, 0);
-        if ( errno ) {
-            syslog(LOG_ERR, "failed to daemonize process. Aborting!\n");
-            return kKEXTReturnError;
-        }
-    }
-
-    k = (KEXTD *)kextd;
-    k->_manager = KEXTManagerCreate(&bcb, &modcbs, NULL, &cfgcbs, kextd,
-        &logErrorFunction, &logMessageFunction, safeBoot, &error);
-    if ( !k->_manager )
-        return error;
-
-    k->_initializing = true;
-    k->_catPort = _KEXTManagerGetMachPort(k->_manager);
-    k->_beVerbose = beVerbose;
-#if TIMERSOURCE
-    k->_pollFileSystem = poll;
-    k->_pollingPeriod = period;
-#endif
-    memset(&sourceContext, NULL, sizeof(CFRunLoopSourceContext));
-
-    error = _KEXTDInitSyslog(k);
-    if ( error != kKEXTReturnSuccess ) {
-        return error;
-    }
-
-    _kextd = kextd;
-
-    if( cdMKextBoot) {
-        KEXTDScanPaths(kextd, true);
-        return kKEXTReturnSuccess;
-    }
-
-    // FIXME: Need a way to make this synchronous!
-    error = KERN2KEXTReturn(IOCatalogueSendData(k->_catPort, kIOCatalogRemoveKernelLinker, 0, 0));
-    if (error != kKEXTReturnSuccess) {
-        syslog(LOG_ERR, "couldn't remove linker from kernel (may have been removed already).",
-            error);
-        // this is only serious the first time kextd launches....
-        // FIXME: how exactly should we handle this? Create a separate program
-        // to trigger KLD unload?
-    }
-    
-    signal(SIGHUP, signalhandler);
-
-    k->_runloop = CFRunLoopGetCurrent();
-    if ( !k->_runloop ) {
-        syslog(LOG_ERR, "error allocating runloop.\n");
-        return NULL;
-    }
-
-    sourceContext.version = 0;
-    sourceContext.info = k;
-    sourceContext.perform = _KEXTDSIGHUPCallout;
-    k->_signalsource = CFRunLoopSourceCreate(kCFAllocatorDefault, 1, &sourceContext);
-    if ( !k->_signalsource ) {
-        syslog(LOG_ERR, "error allocating signal runloop source.\n");
-        return NULL;
-    }
-    CFRunLoopAddSource(k->_runloop, k->_signalsource, kCFRunLoopDefaultMode);
-
-    sourceContext.perform = _KEXTDPerform;
-    k->_kernelsource = CFRunLoopSourceCreate(kCFAllocatorDefault, 2, &sourceContext);
-    if ( !k->_kernelsource ) {
-        syslog(LOG_ERR, "error allocating kernel runloop source.\n");
-        return NULL;
-    }
-    CFRunLoopAddSource(k->_runloop, k->_kernelsource, kCFRunLoopDefaultMode);
-
-    count = CFArrayGetCount(k->_helpers);
-    for ( i = 0; i < count; i++ ) {
-        KEXTDHelper * helper;
-
-        helper = (KEXTDHelper *)CFArrayGetValueAtIndex(k->_helpers, i);
-        if ( !helper )
-            continue;
-
-        if ( helper->cbs.DaemonDidFinishLaunching )
-            helper->cbs.DaemonDidFinishLaunching(helper->context);
-    }
-
-    // Fork off the kmod_control message thread.
-    pthread_attr_init(&kmod_thread_attr);
-    pthread_create(&kmod_thread, &kmod_thread_attr, _KEXTDKmodWait, kextd);
-    pthread_detach(kmod_thread);
-
-    syslog(LOG_INFO, "started.");
-
-    IOCatalogueReset(k->_catPort, kIOCatalogResetDefault);
-    KEXTDScanPaths(kextd, false);
-
-#if TIMERSOURCE
-    if ( poll ) {
-        CFRunLoopTimerRef timer;
-        CFRunLoopTimerContext timerContext = {
-            0, kextd, NULL, NULL, NULL,
-        };
-
-        timer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), period, 0, 10, _KEXTDTimerCallout, &timerContext);
-        if ( !timer ) {
-            syslog(LOG_ERR, "error allocating kmod runloop timer.\n");
-            return kKEXTReturnError;
-        }
-
-        CFRunLoopAddTimer(k->_runloop, timer, kCFRunLoopDefaultMode);
-        CFRelease(timer);
-    }
-#endif
-
-    if ( (error = _KEXTDSendPersonalities(kextd, bootlevel)) != kKEXTReturnSuccess ) {
-        // KEXTError(error, CFSTR("Error sending personalities to IOCatalogue"));
-        syslog(LOG_ERR, "error (%d) sending personalities to IOCatalogue.", error);
-        return error;
-    }
-
-    k->_initializing = false;
-
-    CFRunLoopRun();
-    
-    return kKEXTReturnSuccess;
-}
-
-void KEXTDScanPaths(KEXTDRef kextd, Boolean cdMKextBoot)
-{
-    KEXTReturn error;
-    KEXTD * k;
-    CFIndex count;
-    CFIndex i;
-
-    k = (KEXTD *)kextd;
-    if ( !k->_manager )
-        return;
-    
-    count = CFArrayGetCount(k->_scanPaths);
-    for ( i = 0; i < count; i++ ) {
-        CFURLRef url;
-
-        url = (CFURLRef)CFArrayGetValueAtIndex(k->_scanPaths, i);
-
-        if ( url ) {
-            if ( k->_beVerbose ) {
-                CFStringRef cfstr;
-                char str[256];
-
-                cfstr = CFURLGetString(url);
-                if ( CFStringGetCString(cfstr, str, 256, kCFStringEncodingNonLossyASCII) ) {
-                    syslog(LOG_INFO, "scanning: %s.", str);
-                }
-            }
-            if( !cdMKextBoot) {
-                error = KEXTManagerScanPath(k->_manager, url);
-                if ( error != kKEXTReturnSuccess ) {
-                    syslog(LOG_ERR, "error (%d) scanning path.\n", error);
-                }
-            }
-#if LOOKAPPLENDRV
-	    do {
-                CFURLRef	path;
-		CFArrayRef	array;
-		CFIndex		count, index;
-                SInt32		err;
-
-                path = CFURLCreateCopyAppendingPathComponent(
-                                    kCFAllocatorDefault,
-                                    url,
-                                    CFSTR("AppleNDRV"),
-                                    TRUE);
-                if ( !path )
-		    continue;
-                array = (CFArrayRef)IOURLCreatePropertyFromResource(
-                                            kCFAllocatorDefault, path,
-                                            kIOURLFileDirectoryContents,
-                                            &err);
-		CFRelease( path );
-                if ( !array )
-		    continue;
-
-                count = CFArrayGetCount(array);
-                for ( index = 0; index < count; index++ ) {
-                    CFURLRef file;
-                    file = (CFURLRef) CFArrayGetValueAtIndex(array, index);
-                    if ( !file )
-                        continue;
-                    PEFExamineFile( k->_catPort, file );
-		}
-		CFRelease(array);
-
-            } while( false );
-#endif /* LOOKAPPLENDRV */
-	}
-    }
-}
-
-void KEXTDAddScanPath(KEXTDRef kextd, CFURLRef path)
-{
-    if ( !kextd || !path )
-        return;
-
-    if ( CFURLGetTypeID() != CFGetTypeID(path) )
-        return;
-
-    CFArrayAppendValue(((KEXTD *)kextd)->_scanPaths, path);
-}
-
-void KEXTDRegisterHelperCallbacks(KEXTDRef kextd, KEXTDHelperCallbacks * callbacks)
-{
-    KEXTD * k;
-    KEXTDHelper * helper;
-
-    if ( !kextd || !callbacks )
-        return;
-    
-    k = (KEXTD *)kextd;
-    helper = (KEXTDHelper *)malloc(sizeof(KEXTDHelper));
-    if ( !helper )
-        return;
-
-    helper->cbs.HelperInitialize = callbacks->HelperInitialize;
-    helper->cbs.HelperFinalize = callbacks->HelperFinalize;
-    helper->cbs.DaemonDidFinishLaunching = callbacks->DaemonDidFinishLaunching;
-    helper->cbs.DaemonWillTerminate = callbacks->DaemonWillTerminate;
-    helper->cbs.BundleAdd = callbacks->BundleAdd;
-    helper->cbs.BundleRemove = callbacks->BundleRemove;
-    helper->cbs.EventOccurred = callbacks->EventOccurred;
-    helper->cbs.ModuleWillLoad = callbacks->ModuleWillLoad;
-    helper->cbs.ModuleWasLoaded = callbacks->ModuleWasLoaded;
-    helper->cbs.ModuleLoadError = callbacks->ModuleLoadError;
-
-    helper->context = helper->cbs.HelperInitialize(kextd);
-
-    CFArrayAppendValue(k->_helpers, helper);
-}
-
-KEXTReturn KEXTDLoadModule(KEXTDRef kextd, CFStringRef moduleName)
-{
-    KEXTD * k = (KEXTD *)kextd;
-    KEXTModuleRef module;
-
-    if ( !kextd || !moduleName )
-        return kKEXTReturnBadArgument;
-    
-    module = KEXTManagerGetModule(k->_manager, moduleName);
-    if ( !module )
-        return kKEXTReturnModuleNotFound;
-
-    return KEXTManagerLoadModule(k->_manager, module);
-}
-
-
diff --git a/kextd.tproj/KEXTD.h b/kextd.tproj/KEXTD.h
deleted file mode 100644
index 9cd5055..0000000
--- a/kextd.tproj/KEXTD.h
+++ /dev/null
@@ -1,65 +0,0 @@
-
-#ifndef __KEXTD_H_
-#define __KEXTD_H_
-
-#include <IOKit/kext/KEXTManager.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-typedef struct __KEXTD * KEXTDRef;
-
-typedef enum {
-    kKEXTBootlevelNormal     = 0x00,
-    kKEXTBootlevelExempt     = 0x01,
-    kKEXTBootlevelRecovery   = 0x02,
-    kKEXTBootlevelSingleUser = 0x04,
-    kKEXTBootlevelFlexible   = 0x08,
-    kKEXTBootlevelRequired   = 0x10,
-} KEXTBootlevel;
-
-typedef enum {
-    kKEXTEventReset,
-    kKEXTEventModuleRequest,
-    kKEXTEventPersonalityRequest,
-    kKEXTEventBundleAuthenticationFailed,
-} KEXTEvent;
-
-typedef struct {
-    CFIndex version;
-    void *	(*HelperInitialize)(KEXTDRef kextd);
-    void	(*HelperFinalize)(void * context);
-    void	(*DaemonDidFinishLaunching)(void * context);
-    void	(*DaemonWillTerminate)(void * context);
-    Boolean	(*BundleAdd)(KEXTBundleRef bundle, void * context);
-    Boolean	(*BundleRemove)(KEXTBundleRef bundle, void * context);
-    void	(*EventOccurred)(KEXTEvent event, CFTypeRef data, void * context);
-    Boolean	(*ModuleWillLoad)(KEXTModuleRef module, void * context);
-    void	(*ModuleWasLoaded)(KEXTModuleRef module, void * context);
-    KEXTReturn	(*ModuleLoadError)(KEXTModuleRef module, KEXTReturn error, void * context);
-} KEXTDHelperCallbacks;
-
-
-KEXTDRef	KEXTDCreate(CFArrayRef scanPaths, KEXTReturn * error);
-void		KEXTDFree(KEXTDRef kextd);
-
-void            KEXTDHangup(KEXTDRef kextd);
-void		KEXTDReset(KEXTDRef kextd);
-#if TIMERSOURCE
-KEXTReturn    	KEXTDStartMain(KEXTDRef kextd, Boolean beVerbose, Boolean safeBoot, Boolean debug, Boolean poll, CFIndex period, KEXTBootlevel bootlevel, Boolean cdMKextBoot);
-#else
-KEXTReturn    	KEXTDStartMain(KEXTDRef kextd, Boolean beVerbose, Boolean safeBoot, Boolean debug, KEXTBootlevel bootlevel, Boolean cdMKextBoot);
-#endif
-void		KEXTDScanPaths(KEXTDRef kextd, Boolean cdMKextBoot);
-void		KEXTDAddScanPath(KEXTDRef kextd, CFURLRef path);
-void		KEXTDRegisterHelperCallbacks(KEXTDRef kextd, KEXTDHelperCallbacks * callbacks);
-KEXTReturn      KEXTDKernelRequest(KEXTDRef kextd, CFStringRef moduleName);
-KEXTReturn	KEXTDLoadModule(KEXTDRef kextd, CFStringRef moduleName);
-
-#if defined(__cplusplus)
-} /* "C" */
-#endif
-
-#endif __KEXTD_H_
-
diff --git a/kextd.tproj/KEXTD_main.c b/kextd.tproj/KEXTD_main.c
deleted file mode 100644
index 778b187..0000000
--- a/kextd.tproj/KEXTD_main.c
+++ /dev/null
@@ -1,138 +0,0 @@
-#include <unistd.h>
-#include <CoreFoundation/CoreFoundation.h>
-#include "KEXTD.h"
-
-#define TIMER_PERIOD_S		10
-#define DEFAULT_SEARCH_PATH	"/System/Library/Extensions/"
-
-static const char * arg0 = NULL;
-
-static void usage(void)
-{
-    printf("usage: %s [-v] [-d] [-x] [-j] [-b bootlevel] [-f dirpath]\n", arg0);
-    exit(1);
-}
-
-int main (int argc, const char *argv[])
-{
-    KEXTDRef kextd;
-    KEXTReturn error;
-    KEXTBootlevel bootlevel;
-    CFStringRef str;
-    CFURLRef url;
-    CFMutableArrayRef array;
-    CFIndex period;
-    Boolean safeBoot;
-    Boolean beVerbose;
-    Boolean enableTimer;
-    Boolean debug;
-    Boolean cdMKextBoot;
-    int c;
-
-    arg0 = argv[0];
-    period = TIMER_PERIOD_S;
-    debug = false;
-    safeBoot = false;
-    beVerbose = false;
-    enableTimer = false;
-    cdMKextBoot = false;
-    bootlevel = kKEXTBootlevelNormal;
-
-    url = CFURLCreateWithFileSystemPath(NULL, CFSTR(DEFAULT_SEARCH_PATH), kCFURLPOSIXPathStyle, true);
-    if ( !url ) {
-        printf("Error opening: %s.\n", DEFAULT_SEARCH_PATH);
-        exit(1);
-    }
-    array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-    CFArrayAppendValue(array, url);
-    CFRelease(url);
-
-    while ( (c = getopt(argc, (char **)argv, "xvdjb:f:")) != -1 ) {
-        switch ( c ) {
-
-            case 'x':
-                safeBoot = true;
-                break;
-            case 'v':
-                beVerbose = true;
-                break;
-            case 'd':
-                debug = true;
-                break;
-#if TIMERSOURCE
-            case 'p':
-                if ( !optarg ) {
-                    usage();
-                }
-                else {
-                    period = strtoul(optarg, NULL, 0);
-                    if ( period > 0 )
-                        enableTimer = true;
-                }
-                break;
-#endif
-
-            case 'b':
-                if ( !optarg ) {
-                    usage();
-                }
-                bootlevel = strtoul(optarg, NULL, 0);
-                if ( bootlevel > 0x1f ) {
-                    usage();
-                }
-                break;
-
-            case 'j':
-                cdMKextBoot = true;
-                break;
-                
-            case 'f':
-                if ( !optarg ) {
-                    usage();
-                }
-                str = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingNonLossyASCII);
-                if ( str )
-                    url = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, true);
-                else
-                    url = NULL;
-                if ( !url ) {
-                    printf("Error opening: %s.\n", optarg);
-                } else {
-                    CFArrayAppendValue(array, url);
-                    CFRelease(url);
-                }
-                break;
-
-            default:
-                usage();
-        }
-    }
-    argc -= optind;
-    argv += optind;
-
-    if (argc != 0) {
-        usage();
-    }
-
-    kextd = KEXTDCreate(array, &error);
-    CFRelease(array);
-    if ( !kextd ) {
-        KEXTError(error, CFSTR("Error creating kextd"));
-        exit(error);
-    }
-    
-    KEXTDRegisterHelperCallbacks(kextd, NULL);
-#if TIMERSOURCE
-    error = KEXTDStartMain(kextd, beVerbose, safeBoot, debug, enableTimer, period, bootlevel, cdMKextBoot);
-#else
-    error = KEXTDStartMain(kextd, beVerbose, safeBoot, debug, bootlevel, cdMKextBoot);
-#endif
-    if ( error != kKEXTReturnSuccess ) {
-        KEXTDFree(kextd);
-        KEXTError(error, CFSTR("Error starting kextd"));
-        exit(error);
-    }
-    KEXTDFree(kextd);
-    
-    return error;
-}
diff --git a/kextd.tproj/Makefile b/kextd.tproj/Makefile
deleted file mode 100644
index a43517e..0000000
--- a/kextd.tproj/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Generated by the Apple Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = kextd
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Tool
-
-HFILES = GetSymbolFromPEF.h KEXTD.h PTLock.h
-
-CFILES = KEXTD.c KEXTD_main.c PEFSupport.c PTLock.c
-
-OTHERSRCS = Makefile.preamble Makefile
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /usr/libexec
-WINDOWS_INSTALLDIR = /Library/Executables
-PDO_UNIX_INSTALLDIR = /bin
-LIBS = 
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-
-NEXTSTEP_PB_CFLAGS = -fpascal-strings -Wno-four-char-constants
-
-FRAMEWORKS = -framework CoreFoundation -framework IOKit
-
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
-
-include $(MAKEFILEDIR)/platform.make
-
--include Makefile.preamble
-
-include $(MAKEFILEDIR)/$(MAKEFILE)
-
--include Makefile.postamble
-
--include Makefile.dependencies
diff --git a/kextd.tproj/Makefile.preamble b/kextd.tproj/Makefile.preamble
deleted file mode 100644
index c1624b4..0000000
--- a/kextd.tproj/Makefile.preamble
+++ /dev/null
@@ -1,137 +0,0 @@
-###############################################################################
-#  Makefile.preamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile for configuring the standard application makefiles 
-#  associated with ProjectBuilder. It is included before the main makefile.
-#  In Makefile.preamble you set attributes for a project, so they are available
-#  to the project's makefiles.  In contrast, you typically write additional rules or 
-#  override built-in behavior in the Makefile.postamble.
-#  
-#  Each directory in a project tree (main project plus subprojects) should 
-#  have its own Makefile.preamble and Makefile.postamble.
-###############################################################################
-#
-# Before the main makefile is included for this project, you may set:
-#
-#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
-#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
-
-# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
-# inherited by all nested sub-projects, but the LOCAL_ versions of the same
-# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
-# Build Attributes inspector if at all possible.  To override the default flags
-# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
-# variables below are *inputs* to the build process and distinct from the override
-# settings done (less often) in the Makefile.postamble.
-#
-#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
-#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
-#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
-#	flags in OTHER_MFLAGS, etc.
-#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
-#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
-#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
-#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
-#	precompiling header files
-#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
-#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
-#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
-#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
-#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
-
-# These variables provide hooks enabling you to add behavior at almost every 
-# stage of the make:
-#
-#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
-#    AFTER_PREBUILD: targets to build after installing headers for a subproject
-#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
-#    BEFORE_BUILD: targets to make before a build, but after subprojects
-#    AFTER_BUILD: targets to make after a build
-#
-#    BEFORE_INSTALL: targets to build before installing the product
-#    AFTER_INSTALL: targets to build after installing the product
-#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
-#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
-#
-#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
-#         subproject
-#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
-#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
-#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
-#
-#    BEFORE_DEPEND: targets to build before building dependencies for a
-#	  subproject
-#    AFTER_DEPEND: targets to build after building dependencies for a
-#	  subproject
-#
-#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
-#	  updated every time the project is built.  If NO, the dependency
-#	  file is only built when the depend target is invoked.
-
-# Framework-related variables:
-#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the framework's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-
-# Library-related variables:
-#    PUBLIC_HEADER_DIR:  Determines where public exported header files
-#	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.  For library projects you should
-#       set this to something like /Developer/Headers/$(NAME).  Do not set
-#       this variable for framework projects unless you do not want the
-#       header files included in the framework.
-#    PRIVATE_HEADER_DIR:  Determines where private exported header files
-#  	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.
-#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
-#  	whether the libraries produced are statically linked when they
-#	are used or if they are dynamically loadable. This defaults to
-#       DYNAMIC.
-#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the library's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-#
-#    INSTALL_AS_USER: owner of the intalled products (default root)
-#    INSTALL_AS_GROUP: group of the installed products (default wheel)
-#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
-#
-#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
-#  	passed on the command line to recursive invocations of make.  Note that
-#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
-#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
-#	OTHER_RECURSIVE_VARIABLES. 
-
-# Additional headers to export beyond those in the PB.project:
-#    OTHER_PUBLIC_HEADERS
-#    OTHER_PROJECT_HEADERS
-#    OTHER_PRIVATE_HEADERS
-
-# Additional files for the project's product: <<path relative to proj?>>
-#    OTHER_RESOURCES: (non-localized) resources for this project
-#    OTHER_OFILES: relocatables to be linked into this project
-#    OTHER_LIBS: more libraries to link against
-#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
-#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
-#    OTHER_GARBAGE: additional files to be removed by `make clean'
-
-# Set this to YES if you don't want a final libtool call for a library/framework.
-#    BUILD_OFILES_LIST_ONLY
-
-# To include a version string, project source must exist in a directory named 
-# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
-# OTHER_GENERATED_OFILES = $(VERS_OFILE)
-
-# This definition will suppress stripping of debug symbols when an executable
-# is installed.  By default it is YES.
-# STRIP_ON_INSTALL = NO
-
-# Uncomment to suppress generation of a KeyValueCoding index when installing 
-# frameworks (This index is used by WOB and IB to determine keys available
-# for an object).  Set to YES by default.
-# PREINDEX_FRAMEWORK = NO
-
-# Change this definition to install projects somewhere other than the
-# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
-# and "" on other systems.
-DSTROOT = $(HOME)
diff --git a/kextd.tproj/PB.project b/kextd.tproj/PB.project
deleted file mode 100644
index dd503bf..0000000
--- a/kextd.tproj/PB.project
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-    DYNAMIC_CODE_GEN = YES; 
-    FILESTABLE = {
-        FRAMEWORKS = (CoreFoundation.framework, IOKit.framework); 
-        FRAMEWORKSEARCH = (); 
-        H_FILES = (GetSymbolFromPEF.h, KEXTD.h, PTLock.h); 
-        OTHER_LINKED = (KEXTD.c, KEXTD_main.c, PEFSupport.c, PTLock.c); 
-        OTHER_SOURCES = (Makefile.preamble, Makefile); 
-        SUBPROJECTS = (); 
-    }; 
-    LANGUAGE = English; 
-    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
-    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
-    NEXTSTEP_COMPILEROPTIONS = "-fpascal-strings -Wno-four-char-constants"; 
-    NEXTSTEP_INSTALLDIR = /usr/libexec; 
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
-    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
-    PDO_UNIX_INSTALLDIR = /bin; 
-    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
-    PROJECTNAME = kextd; 
-    PROJECTTYPE = Tool; 
-    PROJECTVERSION = 2.8; 
-    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
-    WINDOWS_INSTALLDIR = /Library/Executables; 
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
-}
diff --git a/kextd.tproj/PEFSupport.c b/kextd.tproj/PEFSupport.c
deleted file mode 100644
index 567f915..0000000
--- a/kextd.tproj/PEFSupport.c
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
-    File:	UnpackPiData.c
-    Written by:	Jeffrey Robbin
-    Copyright:	© 1994, 1996 by Apple Computer, Inc., all rights reserved.
-
-    File:	GetSymbolFromPEF.c
-    Written by:	Jeffrey Robbin
-    Copyright:	© 1994, 1996 by Apple Computer, Inc., all rights reserved.
-*/
-
-#include <IOKit/IOKitLib.h>
-#include <IOKit/kext/KEXTManager.h>
-#include <stdlib.h>
-#include <err.h>
-#include <sys/file.h>
-#include <nlist.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-#include <paths.h>
-
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <mach/mach_host.h>
-
-#include "GetSymbolFromPEF.h"
-
-static unsigned char
-PEFGetNextByte (unsigned char** rawBuffer, long* rawBufferRemaining)
-{
-    *rawBufferRemaining = *rawBufferRemaining - 1;
-    return *(*rawBuffer)++;
-}
-
-
-static unsigned long
-PEFGetCount(unsigned char** rawBuffer, long* rawBufferRemaining)
-{
-    register unsigned char b;
-    register unsigned long value = 0UL;
-
-    /* Scan the count value.  All required bytes MUST be present...                                        */
-
-    b = PEFGetNextByte(rawBuffer, rawBufferRemaining);
-    if (!IS_LAST_PICNT_BYTE(b)) {                            /* if 1st byte is not that last...            */
-        value = CONCAT_PICNT(value, b);                        /*   ...init value using 1st byte            */
-
-        b = PEFGetNextByte(rawBuffer, rawBufferRemaining);
-        if (!IS_LAST_PICNT_BYTE(b)) {                        /*      if 2nd byte is not the last...            */
-            value = CONCAT_PICNT(value, b);                    /*     ...add in 2nd byte                        */
-
-            b = PEFGetNextByte(rawBuffer, rawBufferRemaining);
-            if (!IS_LAST_PICNT_BYTE(b)) {                    /*        if 3rd byte is not the last...         */
-                value = CONCAT_PICNT(value, b);                /*       ...add in 3rd byte                    */
-
-                b = PEFGetNextByte(rawBuffer, rawBufferRemaining);
-                if (!IS_LAST_PICNT_BYTE(b)) {                /*           if 4th byte is not the last...    */
-                    value = CONCAT_PICNT(value, b);            /*           ...add in 4th byte                */
-
-                    /*          5th byte is definitly last!        */
-                    b = PEFGetNextByte(rawBuffer, rawBufferRemaining);
-                }
-            }
-        }
-    }
-
-value = CONCAT_PICNT(value, b);                            /* add in "last" byte (whichever one)        */
-
-return (value);
-}
-
-
-
-// UnpackPiData expands a compressed section into memory.
-
-static OSErr
-UnpackPiData (LogicalAddress        thePEFPtr,
-                    SectionHeaderPtr    sectionHeaderPtr,
-                    LogicalAddress*        theData)
-{
-    long              cntX, cnt, rpt, dcnt, delta;
-    unsigned char    op, b;
-    unsigned char*    unpackBuffer;
-    unsigned char*    originalUnpackBuffer;
-    unsigned char*    endUnpackBuffer;
-    unsigned char*    oldRawBuffer;
-    long            oldRawBufferRemaining;
-    unsigned char*    rawBuffer;
-    long            rawBufferRemaining;
-    
-    // Verify incoming section is packed.
-    if (sectionHeaderPtr->regionKind != kPIDataSection)
-        return (paramErr);
-
-    
-    // Allocate memory to unpack into
-    originalUnpackBuffer = (unsigned char*)NewPtrSys(sectionHeaderPtr->initSize);
-    if (originalUnpackBuffer == nil)
-        return memFullErr;
-
-    unpackBuffer        = originalUnpackBuffer;
-    endUnpackBuffer     = unpackBuffer + sectionHeaderPtr->initSize;
-    rawBuffer            = (unsigned char*)((unsigned long)thePEFPtr + sectionHeaderPtr->containerOffset);
-    rawBufferRemaining    = sectionHeaderPtr->rawSize;
-
-
-    /* Expand the pidata instructions.  EOF will terminate processing through the setjmp    */
-    /* on pidData_jmpbuf above...                                                            */
-
-    while (rawBufferRemaining > 0) {
-
-        /* The first byte of each instruction contains the opcode and a count. If the count    */
-        /* is 0, the count starts in the next byte...                                        */
-
-        /* Pick up the opcode and first count operand...                                    */
-
-        b = PEFGetNextByte(&rawBuffer, &rawBufferRemaining);
-
-        op  = PIOP(b);
-        cnt = PICNT(b);
-
-        if (cnt == 0)
-            cnt = PEFGetCount(&rawBuffer, &rawBufferRemaining);
-
-        /* Unpack the data as a function of the opcode... */
-
-        switch (op) {
-            case kZero:                                    /* zero out cnt bytes...*/
-                if (unpackBuffer + cnt > endUnpackBuffer)
-                    goto Error;
-                memset(unpackBuffer, 0, cnt);
-                unpackBuffer += cnt;
-                break;
-
-            case kBlock:                                  /* copy cnt bytes...*/
-                if (unpackBuffer + cnt > endUnpackBuffer)
-                    goto Error;
-                while (--cnt >= 0)
-                    *unpackBuffer++ = PEFGetNextByte(&rawBuffer, &rawBufferRemaining);
-                    break;
-
-            case kRepeat:                               /* copy cnt bytes rpt times...*/
-                rpt = PEFGetCount(&rawBuffer, &rawBufferRemaining) + 1;
-
-                if (cnt == 1)
-                {
-                    if (unpackBuffer + rpt > endUnpackBuffer)
-                        goto Error;
-                    b = PEFGetNextByte(&rawBuffer, &rawBufferRemaining);
-                    memset(unpackBuffer, b, rpt);
-                    unpackBuffer += rpt;
-                }
-                    else
-                    {
-                        oldRawBufferRemaining    = rawBufferRemaining;
-                        oldRawBuffer            = rawBuffer;
-                        while (--rpt >= 0) {
-                            if (unpackBuffer + cnt > endUnpackBuffer)
-                                goto Error;
-                            rawBufferRemaining    = oldRawBufferRemaining;
-                            rawBuffer            = oldRawBuffer;
-                            cntX = cnt;
-                            while (--cntX >= 0)
-                                *unpackBuffer++ = PEFGetNextByte(&rawBuffer, &rawBufferRemaining);
-                        }
-                    }
-                    break;
-
-            case kRepeatZero:                                                        /* copy cnt 0's and dcnt bytes rpt times*/
-                dcnt              = PEFGetCount(&rawBuffer, &rawBufferRemaining);    /* ...then copy cnt more 0's            */
-                rpt               = PEFGetCount(&rawBuffer, &rawBufferRemaining);
-
-                goto rptPart1;                                        /* jump into loop to copy 0's first...    */
-
-                while (--rpt >= 0) {
-                    if (unpackBuffer + dcnt > endUnpackBuffer)
-                        goto Error;
-                    cntX = dcnt;                                    /* cnt repeating parts follow each other*/
-                    while (--cntX >= 0)
-                        *unpackBuffer++ = PEFGetNextByte(&rawBuffer, &rawBufferRemaining);
-rptPart1:                                                            /* non-repeating part is always 0's...    */
-                        if (unpackBuffer + cnt > endUnpackBuffer)
-                            goto Error;
-                    memset(unpackBuffer, 0, cnt);
-                    unpackBuffer += cnt;
-                }
-
-                    break;
-
-            case kRepeatBlock:                                        /* copy cnt repeating bytes and dcnt         */
-                dcnt              = PEFGetCount(&rawBuffer, &rawBufferRemaining);                    /* non-repating bytes rcnt times...            */
-                rpt               = PEFGetCount(&rawBuffer, &rawBufferRemaining);                    /* ...then copy cnt repeating bytes            */
-
-                oldRawBufferRemaining    = rawBufferRemaining;
-                oldRawBuffer            = rawBuffer;
-                delta                    = 0;                        /*  the repeating part and each non-rep    */
-
-                goto rptPart2;                                        /* jump into loop to copy rptng part 1st*/
-
-                while (--rpt >= 0) {
-                    if (unpackBuffer + dcnt > endUnpackBuffer)
-                        goto Error;
-
-                    rawBuffer            = oldRawBuffer + cnt + delta;
-                    rawBufferRemaining    = oldRawBufferRemaining - (cnt + delta);
-                    cntX = dcnt;
-                    while (--cntX >= 0)
-                        *unpackBuffer++ = PEFGetNextByte(&rawBuffer, &rawBufferRemaining);
-                    delta += dcnt;
-rptPart2:
-                        if (unpackBuffer + cnt > endUnpackBuffer)
-                            goto Error;
-                    rawBuffer            = oldRawBuffer;
-                    rawBufferRemaining    = oldRawBufferRemaining;
-                    cntX = cnt;
-                    while (--cntX >= 0)
-                        *unpackBuffer++ = PEFGetNextByte(&rawBuffer, &rawBufferRemaining);
-                }
-
-                    rawBuffer            = oldRawBuffer + cnt + delta;
-                rawBufferRemaining    = oldRawBufferRemaining - (cnt + delta);
-                break;
-
-            default:
-                goto Error;
-        } /* switch */
-    } /* for */
-    
-    *theData = originalUnpackBuffer;
-        
-    return noErr;
-
-Error:
-    if (unpackBuffer)
-        DisposePtr((Ptr)originalUnpackBuffer);
-    
-    *theData = nil;
-
-    return paramErr;
-}
-
-// GetSymbolFromPEF will extract from a PEF container the data associated
-// with a given symbol name.  It requires that the PEF file have been previously
-// loaded into memory.
-
-static OSStatus
-GetSymbolFromPEF( StringPtr      theSymbolName,
-                    const LogicalAddress thePEFPtr,
-                    LogicalAddress theSymbolPtr,
-                    ByteCount      theSymbolSize )
-{
-    ContainerHeaderPtr		containerHeaderPtr;    // Pointer to the Container Header
-    SectionHeaderPtr		loaderSectionPtr;    // Pointer to the Loader Section Header
-    SectionHeaderPtr		exportSectionPtr;    // Pointer to the Section Header with the symbol
-    short    			currentSection;
-    Boolean  			foundSection;
-    Boolean         		foundSymbol;
-    long                        numExportSymbols;
-    LoaderHeaderPtr      	loaderHeaderPtr;
-    ExportSymbolEntryPtr        exportSymbolEntryPtr;
-    LoaderExportChainEntryPtr	exportChainEntryPtr;
-    StringPtr			exportSymbolName;
-    LogicalAddress		expandedDataPtr;
-    unsigned char*		sourceDataPtr;
-    unsigned char*		destDataPtr;
-
-
-    containerHeaderPtr = (ContainerHeaderPtr)thePEFPtr;
-    
-    // Does the magic cookie match?
-    if (containerHeaderPtr->magicCookie != 'Joy!')
-        return cfragFragmentFormatErr;
-    
-    // Is this a known PEF container format?
-    if (containerHeaderPtr->containerID != 'peff')
-        return cfragFragmentFormatErr;
-    
-    // Validate parameters
-    if (theSymbolPtr == nil)
-        return paramErr;
-
-    
-    // Find the loader section.
-    foundSection = false;
-    for (currentSection = 0; currentSection < containerHeaderPtr->nbrOfSections; currentSection++)
-    {
-        loaderSectionPtr = (SectionHeaderPtr)(    (unsigned long)containerHeaderPtr +
-                                               sizeof(ContainerHeader) +
-                                               (sizeof(SectionHeader) * currentSection));
-        if (loaderSectionPtr->regionKind == kLoaderSection)
-        {
-            foundSection = true;
-            break;
-        }
-    }
-
-    if (foundSection == false)
-        return cfragNoSectionErr;
-    
-    // Get the number of export symbols.
-    loaderHeaderPtr        = (LoaderHeaderPtr)((unsigned long)thePEFPtr + loaderSectionPtr->containerOffset);
-    numExportSymbols    = loaderHeaderPtr->nbrExportSyms;
-    
-    // Start at the first exported symbol.
-    exportSymbolEntryPtr = (ExportSymbolEntryPtr)(    (unsigned long)loaderHeaderPtr +
-                                                   loaderHeaderPtr->slotTblOffset +
-                                                   (sizeof(LoaderHashSlotEntry) * (1<<loaderHeaderPtr->hashSlotTblSz)) +
-                                                   (sizeof(LoaderExportChainEntry) * numExportSymbols));
-
-    exportChainEntryPtr = (LoaderExportChainEntryPtr)(    (unsigned long)loaderHeaderPtr +
-                                                       loaderHeaderPtr->slotTblOffset +
-                                                       (sizeof(LoaderHashSlotEntry) * (1<<loaderHeaderPtr->hashSlotTblSz)));
-
-    foundSymbol = false;
-    while (numExportSymbols-- > 0)
-    {
-        exportSymbolName = (StringPtr)(    (unsigned long)loaderHeaderPtr +
-                                        loaderHeaderPtr->strTblOffset +
-                                        (exportSymbolEntryPtr->class_and_name & 0x00FFFFFF));
-        if (SymbolCompare(theSymbolName, exportSymbolName, exportChainEntryPtr->_h._h_h._nameLength))
-        {
-            foundSymbol = true;
-            break;
-        }
-        exportSymbolEntryPtr = (ExportSymbolEntryPtr)(((int)exportSymbolEntryPtr) + 10);
-        exportChainEntryPtr++;
-    }
-
-    if (foundSymbol == false)
-        return cfragNoSymbolErr;
-
-    
-    // Found the symbol, so... let's go get the data!
-
-    exportSectionPtr = (SectionHeaderPtr)(    (unsigned long)containerHeaderPtr +
-                                           sizeof(ContainerHeader) +
-                                           (sizeof(SectionHeader) * exportSymbolEntryPtr->sectionNumber));
-
-    expandedDataPtr = nil;
-
-    switch (exportSectionPtr -> regionKind)
-    {
-        case kPIDataSection:
-            
-            // Expand the data!  (Not yet... :)
-
-            if (UnpackPiData (thePEFPtr, exportSectionPtr, &expandedDataPtr) != noErr)
-                return cfragFragmentCorruptErr;
-
-            sourceDataPtr = (unsigned char*)((unsigned long)expandedDataPtr +
-                                             exportSymbolEntryPtr->address);
-            break;
-
-        default:
-            sourceDataPtr = (unsigned char*)((unsigned long)thePEFPtr +
-                                             exportSectionPtr->containerOffset +
-                                             exportSymbolEntryPtr->address);
-            break;
-    }
-
-    
-    // Copy the data!
-
-    destDataPtr = (unsigned char*)theSymbolPtr;
-
-
-    while (theSymbolSize-- > 0)
-        *destDataPtr++ = *sourceDataPtr++;
-
-    
-    // Cleanup any expanded data
-
-    if (expandedDataPtr != nil)
-        DisposePtr((Ptr)expandedDataPtr);
-
-    return noErr;
-}
-
-
-static IOByteCount GetPEFLen ( LogicalAddress thePEFPtr)
-{
-    ContainerHeaderPtr		containerHeaderPtr;    // Pointer to the Container Header
-    SectionHeaderPtr		sections;
-    short    			currentSection;
-    long 			lastOffset = 0;
-    long			len = 0;
-
-    containerHeaderPtr = (ContainerHeaderPtr)thePEFPtr;
-    
-    // Does the magic cookie match?
-    if (containerHeaderPtr->magicCookie != 'Joy!')
-        return 0;
-    
-    // Is this a known PEF container format?
-    if (containerHeaderPtr->containerID != 'peff')
-        return 0;
-    
-    // Find the loader section.
-    sections = (SectionHeaderPtr) (containerHeaderPtr + 1);
-    for (currentSection = 0; currentSection < containerHeaderPtr->nbrOfSections; currentSection++)
-    {
-	if( sections[currentSection].containerOffset > lastOffset) {
-	    lastOffset	= sections[currentSection].containerOffset;
-	    len 	= sections[currentSection].rawSize;
-	}
-    }
-
-    return( lastOffset + len );
-}
-
-//
-// SymbolCompare
-//
-// theExportSymbol is NOT null-terminated, so use theExportSymbolLength.
-//
-static Boolean	SymbolCompare (	StringPtr	theLookedForSymbol,
-                                StringPtr	theExportSymbol,
-                                unsigned long	theExportSymbolLength)
-{
-    unsigned char*	p1 = (unsigned char*)theLookedForSymbol;
-    unsigned char*	p2 = (unsigned char*)theExportSymbol;
-    
-	// Same length?
-	// (skip over p string len byte)
-    if ( theExportSymbolLength != *p1++ )
-        return false;
-
-    while ( theExportSymbolLength-- != 0 )
-    {
-        if ( *p1++ != *p2++ )
-            return false;
-    }
-
-    return true;
-}
-
-static int
-readFile(char *path, char **objAddr, long *objSize)
-{
-    int fd;
-    int err;
-    struct stat stat_buf;
-
-    *objAddr = 0;
-    *objSize = 0;
-
-    if((fd = open(path, O_RDONLY)) == -1)
-	return errno;
-
-    do {
-	if(fstat(fd, &stat_buf) == -1) {
-	    err = errno;
-	    continue;
-	}
-	*objSize = stat_buf.st_size;
-
-	if( KERN_SUCCESS != map_fd(fd, 0, (vm_offset_t *) objAddr, TRUE, *objSize)) {
-            *objAddr = 0;
-            *objSize = 0;
-	    err = errno;
-	    continue;
-	}
-
-	err = 0;
-
-    } while( false );
-
-    close(fd);
-
-    return( err );
-}
-
-
-// The Driver Description
-enum {
-  kInitialDriverDescriptor	= 0,
-  kVersionOneDriverDescriptor	= 1,
-  kTheDescriptionSignature	= 'mtej',
-};
-
-struct DriverType {
-  unsigned char nameInfoStr[32]; // Driver Name/Info String
-  unsigned long	version;         // Driver Version Number - really NumVersion
-};
-typedef struct DriverType DriverType;
-
-struct DriverDescription {
-  unsigned long driverDescSignature; // Signature field of this structure
-  unsigned long driverDescVersion;   // Version of this data structure
-  DriverType    driverType;          // Type of Driver
-  char          otherStuff[512];
-};
-typedef struct DriverDescription DriverDescription;
-
-static void
-ExaminePEF( mach_port_t masterPort, char *pef, IOByteCount pefLen, CFArrayRef okList )
-{
-    char              descripName[] = "\pTheDriverDescription";
-    long              err;
-    DriverDescription descrip;
-    DriverDescription curDesc;
-    char              matchName[40];
-    char              okName[40];
-    unsigned long     newVersion;
-    unsigned long     curVersion;
-    IOReturn	      kr;
-    io_iterator_t     iter;
-    io_service_t      service;
-    io_service_t      child;
-    io_string_t	      path;
-    CFStringRef	      ndrvPropName = CFSTR("driver,AAPL,MacOS,PowerPC");
-    CFDataRef	      ndrv;
-    CFMutableDictionaryRef dict;
-    CFIndex	      index;
-    CFStringRef	      okStr;
-    Boolean	      ok;
-
-    err = GetSymbolFromPEF(descripName, pef, &descrip, sizeof(descrip));
-    if(err != 0) {
-        printf("\nGetSymbolFromPEF returns %ld\n",err);
-        return;
-    }
-    if((descrip.driverDescSignature != kTheDescriptionSignature) ||
-        (descrip.driverDescVersion != kInitialDriverDescriptor))
-        return;
-
-    strncpy(matchName, descrip.driverType.nameInfoStr + 1,
-            descrip.driverType.nameInfoStr[0]);
-    matchName[ descrip.driverType.nameInfoStr[0] ] = 0;
-    
-    ok = (!okList);
-    for( index = 0; (!ok) && (index < CFArrayGetCount(okList)); index++) {
-        okStr = CFArrayGetValueAtIndex( okList, index);
-        if( CFStringGetTypeID() != CFGetTypeID(okStr))
-            continue;
-        ok = CFStringGetCString( okStr, okName, sizeof(okName),
-                                kCFStringEncodingMacRoman)
-            && (0 == strcmp( okName, matchName));
-    }
-
-    newVersion = descrip.driverType.version;
-    if((newVersion & 0xffff) == 0x8000)  // final stage, release rev
-        newVersion |= 0xff;
-
-    IOMasterPort(mach_task_self(), &masterPort);
-
-    kr = IOServiceGetMatchingServices(masterPort,
-					IOServiceNameMatching(matchName),
-					&iter);
-    if( kIOReturnSuccess != kr)
-	return;
-    
-    for(
-      ;
-      (service = IOIteratorNext(iter));
-      IOObjectRelease(service)) {
-
-	kr = IORegistryEntryGetPath( service, kIOServicePlane, path );
-        if( kIOReturnSuccess == kr)
-            printf("Name %s matches %s, ", matchName, path);
-        if( !ok) {
-            printf("(skipping)\n");
-            continue;
-        }
-
-	ndrv = (CFDataRef) IORegistryEntryCreateCFProperty( service, ndrvPropName,
-						kCFAllocatorDefault, kNilOptions );
-
-	if( ndrv) {
-            err = GetSymbolFromPEF( descripName, CFDataGetBytePtr(ndrv),
-				    &curDesc, sizeof(curDesc));
-            if (err != noErr)
-                printf("GetSymbolFromPEF returns %ld\n",err);
-            else {
-                if((curDesc.driverDescSignature == kTheDescriptionSignature) &&
-                   (curDesc.driverDescVersion == kInitialDriverDescriptor)) {
-
-                    curVersion = curDesc.driverType.version;
-                    printf("new version %08lx, current version %08lx\n", newVersion, curVersion);
-                    if((curVersion & 0xffff) == 0x8000) // final stage, release rev
-                        curVersion |= 0xff;
-
-                    if( newVersion <= curVersion)
-                        pefLen = 0;
-                }
-	    }
-	    CFRelease(ndrv);
-        }
-
-        if( pefLen == 0)
-	    continue;
-
-	ndrv = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
-					   pef, pefLen, kCFAllocatorNull);
-        if( ndrv == 0)
-	    continue;
-        printf("Installing ndrv (");
-        dict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0,
-                    &kCFTypeDictionaryKeyCallBacks,
-                    &kCFTypeDictionaryValueCallBacks);
-
-	if( dict) {
-            CFDictionarySetValue(dict, ndrvPropName, ndrv);
-	    kr = IORegistryEntryGetChildEntry( service, kIOServicePlane, &child );
-	    if( kr == kIOReturnSuccess) {
-                kr = IORegistryEntrySetCFProperties( child, dict );
-		IOObjectRelease( child );
-	    }
-            CFRelease( dict);
-	} else
-	    kr = kIOReturnNoMemory;
-
-	CFRelease(ndrv);
-        printf("%08x)\n", kr);
-    }
-    IOObjectRelease( iter );
-
-    return;
-}
-
-int
-PEFExamineFile( mach_port_t masterPort, CFURLRef file )
-{
-    char * 		pefBytes;
-    char * 		plistBytes;
-    char * 		pef;
-    long   		pefFileLen, plistLen;
-    IOByteCount		pefLen, pos = 0;
-    int	   		err;
-    CFDictionaryRef	props = 0;
-    CFDataRef		data = 0;
-    CFArrayRef		okList = 0;
-    enum		{ kIOCFMaxPathSize = 1026 };
-    char		cFile[kIOCFMaxPathSize];
-
-    if (CFURLGetFileSystemRepresentation(file, TRUE, cFile, kIOCFMaxPathSize))
-        err = readFile(cFile, &pefBytes, &pefFileLen);
-    else
-        err = kIOReturnIOError;
-    if( err)
-	return( err);
-
-    do {
-        strcat( cFile, ".plist");
-        err = readFile(cFile, &plistBytes, &plistLen);
-        if( err)
-            continue;
-
-        data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault,
-                    plistBytes, plistLen, kCFAllocatorNull);
-        if( !data)
-            continue;
-        props = (CFDictionaryRef) CFPropertyListCreateFromXMLData(
-                            kCFAllocatorDefault, data, kCFPropertyListImmutable, 0 );
-        if( !props)
-            continue;
-        if( CFDictionaryGetTypeID() != CFGetTypeID(props))
-            continue;
-
-        okList = CFDictionaryGetValue( props, CFSTR("IONDRVList") );
-        if( CFArrayGetTypeID() != CFGetTypeID(okList))
-            okList = 0;
-
-    } while( false );
-
-    pef = pefBytes;
-    while( (pos < pefFileLen) && (pefLen = GetPEFLen( pef ))) {
-	ExaminePEF( masterPort, pef, pefLen, okList );
-	pefLen = (pefLen + 15) & ~15;
-	pef += pefLen;
-	pos += pefLen;
-    }
-
-    if( data)
-        CFRelease(data);
-    if( props)
-        CFRelease(props);
-
-    if( plistBytes)
-        vm_deallocate( mach_task_self(), (vm_address_t) plistBytes, plistLen );
-    if( pefBytes)
-        vm_deallocate( mach_task_self(), (vm_address_t) pefBytes, pefFileLen );
-
-    return( 0 );
-}
-
-
-
diff --git a/kextd.tproj/PTLock.c b/kextd.tproj/PTLock.c
deleted file mode 100644
index 92316a5..0000000
--- a/kextd.tproj/PTLock.c
+++ /dev/null
@@ -1,95 +0,0 @@
-
-#include <PTLock.h>
-#include <stdlib.h>
-#include <mach/message.h>
-
-#define mutex_t                pthread_mutex_t
-#define condition_t            pthread_cond_t
-
-#define mutex_init(m)          pthread_mutex_init(m, NULL)
-#define mutex_free(m)          pthread_mutex_destroy(m)
-#define mutex_lock(m)          pthread_mutex_lock(m)
-#define mutex_unlock(m)        pthread_mutex_unlock(m)
-
-#define condition_init(c)      pthread_cond_init(c, NULL)
-#define condition_free(c)      pthread_cond_destroy(c)
-#define condition_wait(c, m)   pthread_cond_wait(c, m)
-#define condition_signal(c)    pthread_cond_signal(c)
-#define condition_broadcast(c) pthread_cond_broadcast(c)
-
-
-typedef struct _PTLock {
-    Boolean locked;
-    pthread_mutex_t m;
-    pthread_cond_t c;
-} PTLock;
-
-
-PTLockRef
-PTLockCreate(void)
-{
-    PTLock * l;
-
-    l = (PTLock *)malloc(sizeof(PTLock));
-    if ( !l )
-        return NULL;
-
-    l->locked = false;
-    mutex_init(&l->m);
-    condition_init(&l->c);
-
-    return (PTLockRef)l;
-}
-
-void
-PTLockFree(PTLockRef lock)
-{
-    PTLock * l = (PTLock *)lock;
-    
-    if ( !lock )
-        return;
-
-    mutex_free(&l->m);
-    condition_free(&l->c);
-    free(lock);
-}
-
-void
-PTLockTakeLock(PTLockRef lock)
-{
-    PTLock * l = (PTLock *)lock;
-
-    mutex_lock(&l->m);
-    while ( l->locked )
-        condition_wait(&l->c, &l->m);
-    l->locked = true;
-    mutex_unlock(&l->m);
-}
-
-void
-PTLockUnlock(PTLockRef lock)
-{
-    PTLock * l = (PTLock *)lock;
-
-    mutex_lock(&l->m);
-    l->locked = false;
-    condition_signal(&l->c);
-    mutex_unlock(&l->m);
-}
-
-Boolean
-PTLockTryLock(PTLockRef lock)
-{
-    PTLock * l = (PTLock *)lock;
-
-    Boolean ret;
-
-    mutex_lock(&l->m);
-    ret = !l->locked;
-    if ( ret )
-        l->locked = true;
-    mutex_unlock(&l->m);
-
-    return ret;
-}
-
diff --git a/kextd.tproj/PTLock.h b/kextd.tproj/PTLock.h
deleted file mode 100644
index 3f18ae5..0000000
--- a/kextd.tproj/PTLock.h
+++ /dev/null
@@ -1,25 +0,0 @@
-
-#ifndef _PTLOCK_H_
-#define _PTLOCK_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-    
-#include <CoreFoundation/CFBase.h>
-#include <pthread.h>
-
-typedef struct __PTLock * PTLockRef;
-
-PTLockRef 	PTLockCreate(void);
-void 		PTLockFree(PTLockRef lock);
-
-Boolean		PTLockTryLock(PTLockRef lock);
-void 		PTLockTakeLock(PTLockRef lock);
-void 		PTLockUnlock(PTLockRef lock);
-
-#ifdef __cplusplus
-}
-#endif
-#endif _PTLOCK_H_
-
diff --git a/kextload.tproj/Makefile.postamble b/kextload.tproj/Makefile.postamble
deleted file mode 100644
index b3bd25c..0000000
--- a/kextload.tproj/Makefile.postamble
+++ /dev/null
@@ -1,9 +0,0 @@
-MAN_PAGE = kextload.8
-MAN_PATH = /usr/share/man/man8
-
-after_install::
-	-mkdir -p ${DSTROOT}$(MAN_PATH)
-	-rm -f ${DSTROOT}$(MAN_PATH)/$(MAN_PAGE)
-	cp $(MAN_PAGE) ${DSTROOT}$(MAN_PATH)/$(MAN_PAGE)
-	chmod og-w ${DSTROOT}$(MAN_PATH)/$(MAN_PAGE)
-
diff --git a/kextload.tproj/Makefile.preamble b/kextload.tproj/Makefile.preamble
deleted file mode 100644
index c1624b4..0000000
--- a/kextload.tproj/Makefile.preamble
+++ /dev/null
@@ -1,137 +0,0 @@
-###############################################################################
-#  Makefile.preamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile for configuring the standard application makefiles 
-#  associated with ProjectBuilder. It is included before the main makefile.
-#  In Makefile.preamble you set attributes for a project, so they are available
-#  to the project's makefiles.  In contrast, you typically write additional rules or 
-#  override built-in behavior in the Makefile.postamble.
-#  
-#  Each directory in a project tree (main project plus subprojects) should 
-#  have its own Makefile.preamble and Makefile.postamble.
-###############################################################################
-#
-# Before the main makefile is included for this project, you may set:
-#
-#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
-#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
-
-# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
-# inherited by all nested sub-projects, but the LOCAL_ versions of the same
-# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
-# Build Attributes inspector if at all possible.  To override the default flags
-# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
-# variables below are *inputs* to the build process and distinct from the override
-# settings done (less often) in the Makefile.postamble.
-#
-#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
-#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
-#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
-#	flags in OTHER_MFLAGS, etc.
-#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
-#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
-#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
-#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
-#	precompiling header files
-#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
-#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
-#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
-#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
-#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
-
-# These variables provide hooks enabling you to add behavior at almost every 
-# stage of the make:
-#
-#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
-#    AFTER_PREBUILD: targets to build after installing headers for a subproject
-#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
-#    BEFORE_BUILD: targets to make before a build, but after subprojects
-#    AFTER_BUILD: targets to make after a build
-#
-#    BEFORE_INSTALL: targets to build before installing the product
-#    AFTER_INSTALL: targets to build after installing the product
-#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
-#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
-#
-#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
-#         subproject
-#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
-#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
-#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
-#
-#    BEFORE_DEPEND: targets to build before building dependencies for a
-#	  subproject
-#    AFTER_DEPEND: targets to build after building dependencies for a
-#	  subproject
-#
-#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
-#	  updated every time the project is built.  If NO, the dependency
-#	  file is only built when the depend target is invoked.
-
-# Framework-related variables:
-#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the framework's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-
-# Library-related variables:
-#    PUBLIC_HEADER_DIR:  Determines where public exported header files
-#	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.  For library projects you should
-#       set this to something like /Developer/Headers/$(NAME).  Do not set
-#       this variable for framework projects unless you do not want the
-#       header files included in the framework.
-#    PRIVATE_HEADER_DIR:  Determines where private exported header files
-#  	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.
-#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
-#  	whether the libraries produced are statically linked when they
-#	are used or if they are dynamically loadable. This defaults to
-#       DYNAMIC.
-#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the library's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-#
-#    INSTALL_AS_USER: owner of the intalled products (default root)
-#    INSTALL_AS_GROUP: group of the installed products (default wheel)
-#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
-#
-#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
-#  	passed on the command line to recursive invocations of make.  Note that
-#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
-#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
-#	OTHER_RECURSIVE_VARIABLES. 
-
-# Additional headers to export beyond those in the PB.project:
-#    OTHER_PUBLIC_HEADERS
-#    OTHER_PROJECT_HEADERS
-#    OTHER_PRIVATE_HEADERS
-
-# Additional files for the project's product: <<path relative to proj?>>
-#    OTHER_RESOURCES: (non-localized) resources for this project
-#    OTHER_OFILES: relocatables to be linked into this project
-#    OTHER_LIBS: more libraries to link against
-#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
-#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
-#    OTHER_GARBAGE: additional files to be removed by `make clean'
-
-# Set this to YES if you don't want a final libtool call for a library/framework.
-#    BUILD_OFILES_LIST_ONLY
-
-# To include a version string, project source must exist in a directory named 
-# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
-# OTHER_GENERATED_OFILES = $(VERS_OFILE)
-
-# This definition will suppress stripping of debug symbols when an executable
-# is installed.  By default it is YES.
-# STRIP_ON_INSTALL = NO
-
-# Uncomment to suppress generation of a KeyValueCoding index when installing 
-# frameworks (This index is used by WOB and IB to determine keys available
-# for an object).  Set to YES by default.
-# PREINDEX_FRAMEWORK = NO
-
-# Change this definition to install projects somewhere other than the
-# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
-# and "" on other systems.
-DSTROOT = $(HOME)
diff --git a/kextload.tproj/PB.project b/kextload.tproj/PB.project
deleted file mode 100644
index d23d6b3..0000000
--- a/kextload.tproj/PB.project
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-    DYNAMIC_CODE_GEN = YES; 
-    FILESTABLE = {
-        FRAMEWORKS = (CoreFoundation.framework, IOKit.framework); 
-        OTHER_LINKED = (kextload_main.c); 
-        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, kextload.8); 
-        SUBPROJECTS = (); 
-    }; 
-    LANGUAGE = English; 
-    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
-    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
-    NEXTSTEP_INSTALLDIR = /sbin; 
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
-    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
-    PDO_UNIX_INSTALLDIR = /bin; 
-    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
-    PROJECTNAME = kextload; 
-    PROJECTTYPE = Tool; 
-    PROJECTVERSION = 2.8; 
-    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
-    WINDOWS_INSTALLDIR = /Library/Executables; 
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
-}
diff --git a/kextload.tproj/kextload.8 b/kextload.tproj/kextload.8
deleted file mode 100644
index e2d34c7..0000000
--- a/kextload.tproj/kextload.8
+++ /dev/null
@@ -1,73 +0,0 @@
-.\"
-.\" Copyright (c) 1997 Doug Rabson
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\"	$Id: kextload.8,v 1.5 2001/01/19 22:51:09 lindak Exp $
-.\"
-.Dd October 11, 1999
-.Dt kextload 8
-.Os FreeBSD
-.Sh NAME
-.Nm kextload
-.Nd loads and starts a kernel extension
-.Sh SYNOPSIS
-.Nm kextload
-.Op Fl i
-.Op Fl v
-.Op Fl h
-.Op Fl x
-.Ar kextbundle
-.Sh DESCRIPTION
-The
-.Nm
-utility loads the module files contained within 
-.Ar kextbundle
-into the kernel and starts their execution either by calling a predefined initialization routine or by passing a personality description to the kernel.  All module dependencies for 
-.Ar kextbundle 
-must reside in /System/Library/Extensions.
-.Pp
-The following options are available:
-.Bl -tag -width indent
-.It Fl v
-Be more verbose.
-.It Fl v
-Simulate safe boot (for testing).
-.It Fl i
-Set interactive mode.
-.It Fl h
-Provide quick help.
-.El
-.Sh FILES
-.Bl -tag -width /modules -compact
-.It Pa /TBD
-directory (bundle) containing loadable kernel modules.
-.Sh DIAGNOSTICS
-The
-.Nm
-utility exits with a status of 0 on success or with a nonzero status if an error occurs.
-.Sh SEE ALSO
-.Xr kmodload 8 ,
-.Xr kmodstat 8 ,
-.Xr kmodsyms 8 ,
-.Xr kmodunload 8
diff --git a/kextload.tproj/kextload_main.c b/kextload.tproj/kextload_main.c
deleted file mode 100644
index 6624995..0000000
--- a/kextload.tproj/kextload_main.c
+++ /dev/null
@@ -1,629 +0,0 @@
-
-#include <stdio.h>
-#include <unistd.h>
-#include <sysexits.h>
-#include <sys/wait.h>
-
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOKitServer.h>
-#include <IOKit/IOCFSerialize.h>
-#include <mach/mach_types.h>
-
-#include <IOKit/kext/KEXTManager.h>
-
-static Boolean sSafeBoot = false;
-static Boolean sVerbose = false;
-static Boolean sInteractive = false;
-static Boolean sAuthenticateAll = false;
-
-static KEXTManagerRef manager = NULL;
-static const char * sCmdName;
-
-#define kBundleIDKey        "CFBundleIdentifier"
-#define kPersonalityNameKey "IOPersonalityName"
-
-#if 0
-// no longer (or never was!) used
-#define kModuleKey         "Module"
-#define kModulesKey        "Modules"
-#define kModuleFileKey     "File"
-#define kPersonalityKey	   "Personality"
-#define kPersonalitiesKey  "Personalities"
-#define kNameKey           "Name"
-#define kVendorKey         "Vendor"
-#define kVersionKey        "Version"
-#define kRequiresKey       "Requires"
-#define kModuleAliasesKey  "Aliases"
-#endif 0
-
-#define kDefaultSearchPath "/System/Library/Extensions"
-
-// these don't seem to be used
-#if 0
-#define kInfoMacOS         "Info-macos"
-#define kInfoMacOSType     "xml"
-#endif 0
-
-static void usage(Boolean help)
-{
-    fprintf(stderr, "Usage: %s [-eihvx] [[-L dir] ...] [-p personality] kextpath\n", sCmdName);
-    if ( help ) {
-        fprintf(stderr, "\t-e   Don't scan System extensions.\n");
-        fprintf(stderr, "\t-h   Help (this menu).\n");
-        fprintf(stderr, "\t-i   Interactive mode.\n");
-        fprintf(stderr, "\t-L   Search Library dir.\n");
-        fprintf(stderr, "\t-p   Personality to load.\n");
-        fprintf(stderr, "\t-v   Verbose mode.\n");
-        fprintf(stderr, "\t-x   Run in safe boot mode.\n");
-    }
-    exit(EX_USAGE);
-}
-
-static void printError(const char * string)
-{
-    fprintf(stderr, string);
-    return;
-}
-
-static void printMessage(const char * string)
-{
-    if (sVerbose) {
-        fprintf(stdout, string);
-    }
-    return;
-}
-
-static Boolean Prompt(CFStringRef message, Boolean defaultValue)
-{
-    Boolean ret;
-    CFIndex len;
-    char * buf;
-    char * dp;
-    char c;
-    char dv;
-
-    ret = false;
-    len = CFStringGetLength(message) + 1;
-    buf = (char *)malloc(sizeof(char) * len);
-    if ( !CFStringGetCString(message, buf, len, kCFStringEncodingASCII) ) {
-        free(buf);
-        return false;
-    }
-    
-    dv = defaultValue?'y':'n';
-    dp = defaultValue?" [Y/n]":" [y/N]";
-    
-    while ( 1 ) {
-        printf(buf);
-        printf(dp);
-        printf("? ");
-        fflush(stdout);
-        fscanf(stdin, "%c", &c);
-        if ( c != 10 ) while ( fgetc(stdin) != 10 );
-        if ( (c == 10) || (tolower(c) == dv) ) {
-            ret = defaultValue;
-            break;
-        }
-        else if ( tolower(c) == 'y' ) {
-            ret = true;
-            break;
-        }
-        else if ( tolower(c) == 'n' ) {
-            ret = false;
-            break;
-        }
-    }
-    free(buf);
-
-    return ret;
-}
-
-static CFURLRef
-URLCreateAbsoluteWithPath(CFStringRef path)
-{
-    CFURLRef url, base;
-
-    url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
-                                        path, kCFURLPOSIXPathStyle, true);
-    base = CFURLCopyAbsoluteURL(url); CFRelease(url);
-    path = CFURLGetString(base);
-    
-    url = CFURLCreateWithString(kCFAllocatorDefault, path, NULL);
-    CFRelease(base);
-
-    return url;
-}
-
-// Override the default authentication scheme so we can load
-// kext not owned by root into the kernel.
-static KEXTReturn authenticate(CFURLRef url, void * context)
-{
-    if ( !sAuthenticateAll ) {
-        KEXTReturn ret;
-        
-        ret = KEXTManagerAuthenticateURL(url);
-        if ( ret != kKEXTReturnSuccess ) {
-            if ( sVerbose ) {
-                CFURLRef absUrl;
-                CFStringRef message;
-                CFStringRef path;
-
-                absUrl = CFURLCopyAbsoluteURL(url);
-                path = CFURLGetString(absUrl);
-
-                message = CFStringCreateWithFormat(
-                                            kCFAllocatorDefault,
-                                            NULL,
-                                            CFSTR("Error (%d) Authentication failed: %@"),
-                                            ret,
-                                            path);
-
-                CFShow(message);
-                CFRelease(message);
-                CFRelease(absUrl);
-            }
-            return ret;
-        }
-    }
-
-    return kKEXTReturnSuccess;
-}
-
-// Print out a message when a module is about to load.
-static Boolean mWillLoad(KEXTManagerRef manager, KEXTModuleRef module, void * context)
-{
-    CFStringRef name;
-    CFStringRef message;
-
-    if ( !sVerbose ) {
-        return true;
-    }
-    
-    name = (CFStringRef)KEXTModuleGetProperty(module, CFSTR(kBundleIDKey));
-    message = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Loading module: %@."), name);
-    CFShow(message);
-    CFRelease(message);
-    
-    return true;
-}
-
-// Print out a message when the module was successfully loaded.
-static void mWasLoaded(KEXTManagerRef manager, KEXTModuleRef module, void * context)
-{
-    CFStringRef name;
-    CFStringRef message;
-
-    if ( !sVerbose ) {
-        return;
-    }
-
-    name = (CFStringRef)KEXTModuleGetProperty(module, CFSTR(kBundleIDKey));
-    message = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Loaded module: %@."), name);
-    CFShow(message);
-    CFRelease(message);
-}
-
-// Print an error message if there was an error loading the module.
-static KEXTReturn mLoadError(KEXTManagerRef manager, KEXTModuleRef module, KEXTReturn error, void * context)
-{
-    CFStringRef name;
-    CFStringRef message;
-
-    name = (CFStringRef)KEXTModuleGetProperty(module, CFSTR(kBundleIDKey));
-    switch ( error ) {
-        case kKEXTReturnModuleAlreadyLoaded:
-
-           /* If the module was already loaded, that isn't an error
-            * as far as kextload is concerned.
-            */
-            error = kKEXTReturnSuccess;
-
-            if ( sVerbose ) {
-                    message = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
-                        CFSTR("Module '%@' is already loaded; continuing."), name);
-                    CFShow(message);
-                    CFRelease(message);
-            }
-            break;
-
-        default:
-            if ( sVerbose ) {
-                message = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
-                    CFSTR("Error loading module '%@'"), name);
-                KEXTError(error, message);
-                CFRelease(message);
-            }
-            break;
-    }
-
-    return error;
-}
-
-// Initialize the KEXTManager.
-static Boolean InitManager(CFArrayRef libList)
-{
-    CFStringRef scanpath;
-    int i, count;
-    CFURLRef url;
-    KEXTReturn error;
-    KEXTManagerBundleLoadingCallbacks bCallback = {
-        0, authenticate, NULL, NULL, NULL, NULL, NULL,
-    };
-    KEXTManagerModuleLoadingCallbacks mCallbacks = {
-        0, mWillLoad, mWasLoaded, mLoadError, NULL, NULL,
-    };
-
-    // Create the manager database.
-    manager = KEXTManagerCreate(&bCallback, &mCallbacks, NULL, NULL, NULL, &printError, &printMessage, sSafeBoot, &error);
-    if ( !manager ) {
-        fprintf(stderr, "Manager not created.\n");
-        return false;
-    }
-
-    for (i = 0, count = CFArrayGetCount(libList); i < count; i++) {
-        scanpath = CFArrayGetValueAtIndex(libList, i);
-        url = URLCreateAbsoluteWithPath(scanpath);
-        // Now scan in all the bundles in the extensions directory.
-        error = KEXTManagerScanPath(manager, url);
-        CFRelease(url);
-        if (error != kKEXTReturnSuccess) {
-            if (sVerbose) {
-                CFStringRef errMsg = CFStringCreateWithFormat(
-                                        kCFAllocatorDefault,
-                                        NULL,
-                                        CFSTR("Error scanning path - %@"),
-                                        scanpath);
-                KEXTError(error, errMsg);
-            }
-        };
-    }
-
-    return true;
-}
-
-static void PromptForLoading(void * val, void * context)
-{
-    KEXTPersonalityRef person;
-    CFMutableArrayRef toLoad;
-    Boolean boolval;
-
-    person = val;
-    toLoad = context;
-
-    boolval = true;
-    if ( sInteractive ) {
-        CFStringRef name;
-
-        name = KEXTPersonalityGetProperty(person, CFSTR(kBundleIDKey));
-        if ( name ) {
-            CFStringRef message;
-            
-            message = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Load personality '%@'"), name);
-            boolval = Prompt(message, true);
-            CFRelease(message);
-        }
-    }
-
-    if ( boolval ) {
-        CFArrayAppendValue(toLoad, person);
-    }
-}
-
-static void ArrayGetModuleList(void * val, void * context[])
-{
-    KEXTPersonalityRef person;
-    KEXTModuleRef module;
-    KEXTReturn error;
-    CFMutableArrayRef modules;
-    CFStringRef name;
-    CFStringRef modName;
-    CFStringRef message;
-
-    person = val;
-    modules = context[0];
-    error = *(KEXTReturn *)context[1];
-
-    if ( error != kKEXTReturnSuccess ) {
-        return;
-    }
-
-    // Once we have the personality entity, we can
-    // attempt to load it into the kernel...
-    modName = KEXTPersonalityGetProperty(person, CFSTR(kBundleIDKey));
-    if ( !modName ) {
-        name = KEXTPersonalityGetProperty(person, CFSTR(kBundleIDKey));
-        message = CFStringCreateWithFormat(kCFAllocatorDefault,
-                                            NULL,
-                                            CFSTR("Error: '%@' has no Module key."),
-                                            name);
-        CFShow(message);
-        CFRelease(message);
-
-        if ( sInteractive ) {
-            if ( !Prompt(CFSTR("Continue"), true) ) {
-                *(KEXTReturn *)(context[1]) = error;
-                return;
-            }
-        }
-        return;
-    }
-
-    module = KEXTManagerGetModule(manager, modName);
-    if ( module ) {
-        CFRange range;
-
-        range = CFRangeMake(0, CFArrayGetCount(modules));
-        if ( !CFArrayContainsValue(modules, range, module) ) {
-            CFArrayAppendValue(modules, module);
-        }
-    }
-}
-
-static void ArrayLoadMods(void * val, void * context)
-{
-    KEXTModuleRef mod;
-    KEXTReturn error;
-    Boolean boolval;
-
-    error = *(KEXTReturn *)context;
-    if ( error != kKEXTReturnSuccess ) {
-        return;
-    }
-
-    mod = val;
-    
-    boolval = true;
-    if ( sInteractive ) {
-        CFStringRef name;
-
-        name = KEXTModuleGetProperty(mod, CFSTR(kBundleIDKey));
-        if ( name ) {
-            CFStringRef message;
-
-            message = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Load module '%@'"), name);
-            boolval = Prompt(message, true);
-            CFRelease(message);
-        }
-    }
-
-    if ( boolval ) {
-        error = KEXTManagerLoadModule(manager, mod);
-        if ( error != kKEXTReturnSuccess ) {
-            KEXTError(error, CFSTR("Error loading module"));
-            *(KEXTReturn *)context = error;
-        }
-    }
-}
-
-static KEXTReturn LoadAllModules(KEXTBundleRef bundle)
-{
-    CFArrayRef modules;
-    CFRange range;
-    KEXTReturn error;
-
-    if ( !bundle ) {
-        return kKEXTReturnBadArgument;
-    }
-    
-    modules = KEXTManagerCopyModulesForBundle(manager, bundle);
-    if ( !modules ) {
-        return kKEXTReturnModuleNotFound;
-    }
-
-    error = kKEXTReturnSuccess;
-    range = CFRangeMake(0, CFArrayGetCount(modules));
-    CFArrayApplyFunction(modules, range, (CFArrayApplierFunction)ArrayLoadMods, &error);
-
-    CFRelease(modules);
-
-    return error;
-}
-
-static KEXTReturn LoadAllPersonalities(KEXTBundleRef bundle)
-{
-    CFArrayRef array;
-    CFArrayRef configs;
-    CFMutableArrayRef toLoad;
-    CFMutableArrayRef modules;
-    CFRange range;
-    KEXTReturn error;
-    void * context[2];
-
-    error = kKEXTReturnSuccess;
-
-    // Get the configurations associated with this bundle.
-    configs = KEXTManagerCopyConfigsForBundle(manager, bundle);
-
-    // Get the personality entities associated with
-    // this particular bundle.  We use these keys to aquire\
-    // personality entities from the database.
-    array = KEXTManagerCopyPersonalitiesForBundle(manager, bundle);
-
-    if ( !array && !configs ) {
-        return kKEXTReturnPersonalityNotFound;
-    }
-
-    // This is the list of personalities and configurations to load.
-    toLoad = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-    modules = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-
-    if ( configs ) {
-        range = CFRangeMake(0, CFArrayGetCount(configs));
-        CFArrayApplyFunction(configs, range, (CFArrayApplierFunction)PromptForLoading, toLoad);
-        CFRelease(configs);
-    }
-
-    if ( array ) {
-        range = CFRangeMake(0, CFArrayGetCount(array));
-        CFArrayApplyFunction(array, range, (CFArrayApplierFunction)PromptForLoading, toLoad);
-        CFRelease(array);
-    }
-
-    context[0] = modules;
-    context[1] = &error;
-
-    range = CFRangeMake(0, CFArrayGetCount(toLoad));
-    CFArrayApplyFunction(toLoad, range, (CFArrayApplierFunction)ArrayGetModuleList, context);
-
-    if ( error != kKEXTReturnSuccess ) {
-        CFRelease(toLoad);
-        CFRelease(modules);
-        return error;
-    }
-
-    // Load all the modules.
-    sInteractive = false;
-    range = CFRangeMake(0, CFArrayGetCount(modules));
-    CFArrayApplyFunction(modules, range, (CFArrayApplierFunction)ArrayLoadMods, &error);
-    sInteractive = true;
-
-    if ( error != kKEXTReturnSuccess ) {
-        CFRelease(toLoad);
-        CFRelease(modules);
-        return error;
-    }
-    
-    // We need to send all personalities together.
-    error = KEXTManagerLoadPersonalities(manager, toLoad);
-    CFRelease(toLoad);
-    CFRelease(modules);
-
-    return error;
-}
-
-int main (int argc, const char *argv[])
-{
-    int c;
-
-    CFMutableArrayRef libList;
-    CFURLRef abs;
-    CFStringRef defaultLibDir = NULL;
-    CFStringRef path;
-    CFStringRef name;
-    KEXTBundleRef bundle;
-    KEXTReturn error;
-
-    sCmdName = argv[0];
-
-    name  = NULL;
-    defaultLibDir = CFSTR(kDefaultSearchPath);
-    libList = CFArrayCreateMutable
-                (kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-    if (!libList) {
-        fprintf(stderr, "%s: Not enough memory to run\n", sCmdName);
-        exit(EX_SOFTWARE);
-    }
-
-    while ( (c = getopt(argc, (char **)argv, "eihvxp:L:")) != -1 ) {
-        switch ( c ) {
-        case 'e':
-            defaultLibDir = NULL;
-            break;
-
-        case 'v':
-            sVerbose = true;
-            break;
-
-        case 'x':
-            sSafeBoot = true;
-            break;
-
-        case 'i':
-            sInteractive = true;
-            break;
-
-        case 'h':
-            usage(true);
-
-        case 'L':
-            if ( !optarg )
-                usage(false);
-            else if (strlen(optarg)) {
-                path = CFStringCreateWithCString
-                    (kCFAllocatorDefault, optarg, kCFStringEncodingASCII);
-                CFArrayAppendValue(libList, path);
-                CFRelease(path);
-            }
-
-        case 'p':
-            if ( !optarg )
-                usage(false);
-            else
-                name = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingASCII);
-            break;
-
-        default:
-            usage(false);
-        }
-    }
-    argc -= optind;
-    argv += optind;
-
-    if (argc < 1)
-        usage(false);
-
-    if (defaultLibDir)
-        CFArrayInsertValueAtIndex(libList, 0, defaultLibDir);
-
-    path = CFStringCreateWithCString
-            (kCFAllocatorDefault, argv[argc - 1], kCFStringEncodingASCII);
-    abs = URLCreateAbsoluteWithPath(path);
-    CFRelease(path);
-
-    if ( !abs ) {
-        fprintf(stderr, "Invalid path: %s.\n", argv[argc - 1]);
-        CFRelease(abs);
-        exit(-1);
-    }
-
-    if ( sVerbose ) {
-        fprintf(stderr, "Examining: %s\n", argv[argc - 1]);
-    }
-
-    sAuthenticateAll = false;
-    if ( !InitManager(libList) ) {
-        fprintf(stderr, "Error initializing KEXT Manager.\n");
-        exit(-1);
-    }
-
-    // Don't authenticate the target bundle, this
-    // is just a convenience for developers.
-    sAuthenticateAll = true;
-    
-    // Add the bundle to the database.
-    error = KEXTManagerAddBundle(manager, abs);
-    if ( error != kKEXTReturnSuccess ) {
-        fprintf(stderr, "Error (%d) adding bundle to database.\n", error);
-        exit(1);
-    }
-    // Re-enable the authentication.
-    sAuthenticateAll = false;
-    // Now, get the bundle entity from the database,
-    // this is the handle we use for accessing bundle resources.
-    bundle = KEXTManagerGetBundleWithURL(manager, abs);
-    if ( !bundle ) {
-        fprintf(stderr, "Bundle not found in database.\n");
-        exit(EX_DATAERR);
-    }
-
-    // If no name was given, then assume all personalities should be loaded.
-    error = LoadAllPersonalities(bundle);
-    if ( error != kKEXTReturnSuccess ) {
-        // No personalities are found, then this is probably
-        // a kmod bundle.  Try loading just the modules.
-        if ( error == kKEXTReturnPersonalityNotFound ) {
-            // XXX -- Attempt to load modules.
-            LoadAllModules(bundle);
-        }
-    }
-
-    if ( manager ) {
-        KEXTManagerRelease(manager);
-    }
-
-    if ( sVerbose ) {
-        printf("Done.\n");
-    }
-
-    return 0;      // ...and make main fit the ANSI spec.
-}
diff --git a/kextunload.tproj/Makefile b/kextunload.tproj/Makefile
deleted file mode 100644
index 2df3398..0000000
--- a/kextunload.tproj/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-#
-# Generated by the Apple Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = kextunload
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Tool
-
-CFILES = kextunload_main.c
-
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble kextunload.8
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /sbin
-WINDOWS_INSTALLDIR = /Library/Executables
-PDO_UNIX_INSTALLDIR = /bin
-LIBS = 
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-
-FRAMEWORKS = -framework CoreFoundation -framework IOKit
-
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
-
-include $(MAKEFILEDIR)/platform.make
-
--include Makefile.preamble
-
-include $(MAKEFILEDIR)/$(MAKEFILE)
-
--include Makefile.postamble
-
--include Makefile.dependencies
diff --git a/kextunload.tproj/Makefile.postamble b/kextunload.tproj/Makefile.postamble
deleted file mode 100644
index 15092aa..0000000
--- a/kextunload.tproj/Makefile.postamble
+++ /dev/null
@@ -1,9 +0,0 @@
-MAN_PAGE = kextunload.8
-MAN_PATH = /usr/share/man/man8
-
-after_install::
-	-mkdir -p ${DSTROOT}$(MAN_PATH)
-	-rm -f ${DSTROOT}$(MAN_PATH)/$(MAN_PAGE)
-	cp $(MAN_PAGE) ${DSTROOT}$(MAN_PATH)/$(MAN_PAGE)
-	chmod og-w ${DSTROOT}$(MAN_PATH)/$(MAN_PAGE)
-
diff --git a/kextunload.tproj/Makefile.preamble b/kextunload.tproj/Makefile.preamble
deleted file mode 100644
index c1624b4..0000000
--- a/kextunload.tproj/Makefile.preamble
+++ /dev/null
@@ -1,137 +0,0 @@
-###############################################################################
-#  Makefile.preamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile for configuring the standard application makefiles 
-#  associated with ProjectBuilder. It is included before the main makefile.
-#  In Makefile.preamble you set attributes for a project, so they are available
-#  to the project's makefiles.  In contrast, you typically write additional rules or 
-#  override built-in behavior in the Makefile.postamble.
-#  
-#  Each directory in a project tree (main project plus subprojects) should 
-#  have its own Makefile.preamble and Makefile.postamble.
-###############################################################################
-#
-# Before the main makefile is included for this project, you may set:
-#
-#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
-#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
-
-# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
-# inherited by all nested sub-projects, but the LOCAL_ versions of the same
-# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
-# Build Attributes inspector if at all possible.  To override the default flags
-# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
-# variables below are *inputs* to the build process and distinct from the override
-# settings done (less often) in the Makefile.postamble.
-#
-#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
-#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
-#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
-#	flags in OTHER_MFLAGS, etc.
-#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
-#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
-#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
-#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
-#	precompiling header files
-#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
-#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
-#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
-#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
-#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
-
-# These variables provide hooks enabling you to add behavior at almost every 
-# stage of the make:
-#
-#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
-#    AFTER_PREBUILD: targets to build after installing headers for a subproject
-#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
-#    BEFORE_BUILD: targets to make before a build, but after subprojects
-#    AFTER_BUILD: targets to make after a build
-#
-#    BEFORE_INSTALL: targets to build before installing the product
-#    AFTER_INSTALL: targets to build after installing the product
-#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
-#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
-#
-#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
-#         subproject
-#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
-#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
-#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
-#
-#    BEFORE_DEPEND: targets to build before building dependencies for a
-#	  subproject
-#    AFTER_DEPEND: targets to build after building dependencies for a
-#	  subproject
-#
-#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
-#	  updated every time the project is built.  If NO, the dependency
-#	  file is only built when the depend target is invoked.
-
-# Framework-related variables:
-#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the framework's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-
-# Library-related variables:
-#    PUBLIC_HEADER_DIR:  Determines where public exported header files
-#	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.  For library projects you should
-#       set this to something like /Developer/Headers/$(NAME).  Do not set
-#       this variable for framework projects unless you do not want the
-#       header files included in the framework.
-#    PRIVATE_HEADER_DIR:  Determines where private exported header files
-#  	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.
-#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
-#  	whether the libraries produced are statically linked when they
-#	are used or if they are dynamically loadable. This defaults to
-#       DYNAMIC.
-#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the library's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-#
-#    INSTALL_AS_USER: owner of the intalled products (default root)
-#    INSTALL_AS_GROUP: group of the installed products (default wheel)
-#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
-#
-#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
-#  	passed on the command line to recursive invocations of make.  Note that
-#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
-#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
-#	OTHER_RECURSIVE_VARIABLES. 
-
-# Additional headers to export beyond those in the PB.project:
-#    OTHER_PUBLIC_HEADERS
-#    OTHER_PROJECT_HEADERS
-#    OTHER_PRIVATE_HEADERS
-
-# Additional files for the project's product: <<path relative to proj?>>
-#    OTHER_RESOURCES: (non-localized) resources for this project
-#    OTHER_OFILES: relocatables to be linked into this project
-#    OTHER_LIBS: more libraries to link against
-#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
-#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
-#    OTHER_GARBAGE: additional files to be removed by `make clean'
-
-# Set this to YES if you don't want a final libtool call for a library/framework.
-#    BUILD_OFILES_LIST_ONLY
-
-# To include a version string, project source must exist in a directory named 
-# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
-# OTHER_GENERATED_OFILES = $(VERS_OFILE)
-
-# This definition will suppress stripping of debug symbols when an executable
-# is installed.  By default it is YES.
-# STRIP_ON_INSTALL = NO
-
-# Uncomment to suppress generation of a KeyValueCoding index when installing 
-# frameworks (This index is used by WOB and IB to determine keys available
-# for an object).  Set to YES by default.
-# PREINDEX_FRAMEWORK = NO
-
-# Change this definition to install projects somewhere other than the
-# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
-# and "" on other systems.
-DSTROOT = $(HOME)
diff --git a/kextunload.tproj/PB.project b/kextunload.tproj/PB.project
deleted file mode 100644
index 3b29511..0000000
--- a/kextunload.tproj/PB.project
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-    DYNAMIC_CODE_GEN = YES; 
-    FILESTABLE = {
-        FRAMEWORKS = (CoreFoundation.framework, IOKit.framework); 
-        OTHER_LINKED = (kextunload_main.c); 
-        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, kextunload.8); 
-    }; 
-    LANGUAGE = English; 
-    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
-    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
-    NEXTSTEP_INSTALLDIR = /sbin; 
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
-    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
-    PDO_UNIX_INSTALLDIR = /bin; 
-    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
-    PROJECTNAME = kextunload; 
-    PROJECTTYPE = Tool; 
-    PROJECTVERSION = 2.8; 
-    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
-    WINDOWS_INSTALLDIR = /Library/Executables; 
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
-}
diff --git a/kextunload.tproj/kextunload.8 b/kextunload.tproj/kextunload.8
deleted file mode 100644
index f622928..0000000
--- a/kextunload.tproj/kextunload.8
+++ /dev/null
@@ -1,43 +0,0 @@
-.\"
-.\"
-.Dd July 5, 2000
-.Dt kextunload 8
-.Os Apple Computer, Inc.
-.Sh NAME
-.Nm kextunload
-.Nd terminates classes, unloads modules associated with a kernel extension
-.Sh SYNOPSIS
-.Nm kextunload
-.Op Fl c Ar classname
-.Op Fl m Ar modulename
-.Op Fl h
-.Op Ar kextbundle
-.Sh DESCRIPTION
-The
-.Nm
-utility terminates classes and unloads the module files contained within 
-.Ar kextbundle
-or with a given name. Modules and classes in the kernel must be written correctly to handle the termination and unload process for this to be successful.
-.Pp
-The following options are available:
-.Bl -tag -width indent
-.It Fl h
-Provide quick help.
-.It Fl m
-Terminate the classes found in the module name given, and unload the module.
-.It Fl c
-Terminate the classes in the kernel with the given name.
-.El
-.Sh FILES
-.Bl -tag -width /modules -compact
-.Ar kextbundle
-directory containing loadable kernel modules.
-.Sh DIAGNOSTICS
-The
-.Nm
-utility exits with a status of 0 on success or with a nonzero status if an error occurs.
-.Sh SEE ALSO
-.Xr kextload 8 ,
-.Xr kmodload 8 ,
-.Xr kmodstat 8 ,
-.Xr kmodunload 8
diff --git a/kextunload.tproj/kextunload_main.c b/kextunload.tproj/kextunload_main.c
deleted file mode 100644
index 852cd2c..0000000
--- a/kextunload.tproj/kextunload_main.c
+++ /dev/null
@@ -1,278 +0,0 @@
-
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOKitServer.h>
-#include <IOKit/IOCFSerialize.h>
-#include <mach/mach_types.h>
-
-#include <IOKit/kext/KEXTManager.h>
-
-static Boolean sVerbose = false;
-static Boolean sAuthenticateAll = false;
-
-static KEXTManagerRef manager = NULL;
-static const char * sArgv0;
-static mach_port_t sMasterPort;
-
-#define kBundleIDKey       "CFBundleIdentifier"
-
-
-#if 0
-// never were used
-#define kModuleKey         "Module"
-#define kModulesKey        "Modules"
-#define kModuleFileKey     "File"
-#define kPersonalityKey	   "Personality"
-#define kPersonalitiesKey  "Personalities"
-#define kNameKey           "Name"
-#define kVendorKey         "Vendor"
-#define kVersionKey        "Version"
-#define kRequiresKey       "Requires"
-#define kModuleAliasesKey  "Aliases"
-#endif 0
-
-
-#define kDefaultSearchPath "/System/Library/Extensions"
-
-// These don't seem to be used
-#if 0
-#define kInfoMacOS         "Info-macos"
-#define kInfoMacOSType     "xml"
-#endif 0
-
-#define defaultPath CFSTR(kDefaultSearchPath)
-
-
-static void usage(Boolean help)
-{
-    printf("Usage: %s [-h] [-m modulename] [-c classname] [kextpath]\n", sArgv0);
-    exit(-1);
-}
-
-
-// Override the default authentication scheme so we can load
-// kext not owned by root into the kernel.
-static KEXTReturn authenticate(CFURLRef url, void * context)
-{
-    if ( !sAuthenticateAll ) {
-        KEXTReturn ret;
-        
-        ret = KEXTManagerAuthenticateURL(url);
-        if ( ret != kKEXTReturnSuccess ) {
-            if ( sVerbose ) {
-                CFURLRef absUrl;
-                CFStringRef message;
-                CFStringRef path;
-
-                absUrl = CFURLCopyAbsoluteURL(url);
-                path = CFURLGetString(absUrl);
-
-                message = CFStringCreateWithFormat(
-                                            kCFAllocatorDefault,
-                                            NULL,
-                                            CFSTR("Error (%) Authentication failed: %@"),
-                                            ret,
-                                            path);
-
-                CFShow(message);
-                CFRelease(message);
-                CFRelease(absUrl);
-            }
-            return ret;
-        }
-    }
-
-    return kKEXTReturnSuccess;
-}
-
-// Initialize the KEXTManager.
-static Boolean InitManager(void)
-{
-    CFURLRef url;
-    KEXTReturn error;
-    KEXTManagerBundleLoadingCallbacks bCallback = {
-        0, authenticate, NULL, NULL, NULL, NULL, NULL,
-    };
-    KEXTManagerModuleLoadingCallbacks mCallbacks = {
-        0, NULL, NULL, NULL, NULL, NULL,
-    };
-
-    // Give the manager the default path to the Extensions folder.
-    // This is needed for dependency matching.
-    url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, defaultPath, kCFURLPOSIXPathStyle, true);
-
-    // Create the manager database.
-    manager = KEXTManagerCreate(&bCallback, &mCallbacks, NULL, NULL, NULL, NULL, NULL, false, &error);
-    if ( !manager ) {
-        printf("Manager not created.\n");
-        return false;
-    }
-
-    // Now scan in all the bundles in the extensions directory.
-    if ( (error = KEXTManagerScanPath(manager, url)) != kKEXTReturnSuccess ) {
-        if ( sVerbose ) {
-            KEXTError(error, CFSTR("Error scanning path"));
-        }
-        return false;
-    };
-
-    return true;
-}
-
-
-static KEXTReturn KEXTUnloadAllModules(KEXTBundleRef bundle)
-{
-    CFArrayRef modules;
-    kern_return_t kr;
-    KEXTModuleRef mod;
-    char buf[256];
-    unsigned int i;
-    CFIndex count;
-
-    if ( !bundle ) {
-        return kKEXTReturnBadArgument;
-    }
-    
-    modules = KEXTManagerCopyModulesForBundle(manager, bundle);
-    if ( !modules ) {
-        return kKEXTReturnModuleNotFound;
-    }
-    
-    for( i = 0, count = CFArrayGetCount(modules); i < count; i++) {
-        CFStringRef name;
-
-        mod = (KEXTModuleRef) CFArrayGetValueAtIndex( modules, i);
-        name = KEXTModuleGetProperty( mod, CFSTR(kBundleIDKey));
-
-        if( CFStringGetCString( name, buf, sizeof(buf), kCFStringEncodingMacRoman)) {
-   
-            kr = IOCatalogueTerminate( sMasterPort, kIOCatalogModuleUnload, buf );
-            printf("IOCatalogueTerminate(Module %s) [%x]\n", buf, kr);
-        }
-    }
-
-    CFRelease(modules);
-
-    return kKEXTReturnSuccess;
-}
-
-KEXTReturn KEXTUnload( const char * cPath )
-{
-    CFURLRef url;
-    CFURLRef abs;
-    CFStringRef path;
-    KEXTBundleRef bundle;
-    KEXTReturn error;
-
-    path = CFStringCreateWithCString(kCFAllocatorDefault, cPath, kCFStringEncodingASCII);
-    url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, true);
-    CFRelease(path);
-    
-    abs = CFURLCopyAbsoluteURL(url);
-    CFRelease(url);
-
-    if ( !abs ) {
-        printf("Invalid path: %s.\n", cPath);
-        CFRelease(abs);
-        exit(-1);
-    }
-
-    sAuthenticateAll = false;
-    if ( !InitManager() ) {
-        printf("Error initializing KEXT Manager.\n");
-        exit(-1);
-    }
-
-    // Don't authenticate the target bundle, this
-    // is just a convenience for developers.
-    sAuthenticateAll = true;
-    
-    // Add the bundle to the database.
-    error = KEXTManagerAddBundle(manager, abs);
-    if ( error != kKEXTReturnSuccess ) {
-        printf("Error (%d) adding bundle to database.\n", error);
-        exit(1);
-    }
-    // Re-enable the authentication.
-    sAuthenticateAll = false;
-    // Now, get the bundle entity from the database,
-    // this is the handle we use for accessing bundle resources.
-    bundle = KEXTManagerGetBundleWithURL(manager, abs);
-    if ( !bundle ) {
-        printf("Bundle not found in database.\n");
-        exit(1);
-    }
-
-    error = KEXTUnloadAllModules(bundle);
-
-    if ( manager ) {
-        KEXTManagerRelease(manager);
-    }
-
-    return( error );
-}
-
-int main (int argc, const char *argv[])
-{
-    int c;
-    const char * name  = NULL;
-    int command = 0;
-    KEXTReturn error;
-    kern_return_t kr;
-
-    // Obtain the I/O Kit communication handle.
-    kr = IOMasterPort(bootstrap_port, &sMasterPort);
-    if( kr != KERN_SUCCESS)
-        exit(-1);
-
-    sArgv0 = argv[0];
-
-    if (argc < 2)
-        usage(false);
-
-    while ( (c = getopt(argc, (char **)argv, "hm:c:")) != -1 ) {
-        switch ( c ) {
-
-            case 'h':
-                usage(true);
-
-            case 'c':
-                command = kIOCatalogServiceTerminate;
-                if ( !optarg )
-                    usage(false);
-                else
-                    name = optarg;
-                break;
-
-            case 'm':
-                command = kIOCatalogModuleUnload;
-                if ( !optarg )
-                    usage(false);
-                else
-                    name = optarg;
-                break;
-
-            default:
-                usage(false);
-        }
-    }
-
-    argc -= optind;
-    argv += optind;
-    if (argc >= 1) {
-        name = argv[argc - 1];
-        error = KEXTUnload( name );
-    }
-
-    if( command >= kIOCatalogModuleUnload) {
-        kr = IOCatalogueTerminate( sMasterPort, command, (char *) name );
-        printf("IOCatalogueTerminate(%s %s) [%x]\n",
-            (command == kIOCatalogModuleUnload) ? "Module" : "Class",
-            name, kr);
-    }
-    printf("done.\n");
-
-    return 0;      // ...and make main fit the ANSI spec.
-}
diff --git a/kmodload.tproj/Makefile b/kmodload.tproj/Makefile
deleted file mode 100644
index 508f918..0000000
--- a/kmodload.tproj/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# Generated by the Apple Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = kmodload
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Tool
-
-HFILES = kld_patch.h
-
-CFILES = kld_patch.c kmodload.c
-
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble kmodload.8\
-            kmodsyms.8
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /sbin
-WINDOWS_INSTALLDIR = /Library/Executables
-PDO_UNIX_INSTALLDIR = /bin
-LIBS = -lkld
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-
-
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
-
-include $(MAKEFILEDIR)/platform.make
-
--include Makefile.preamble
-
-include $(MAKEFILEDIR)/$(MAKEFILE)
-
--include Makefile.postamble
-
--include Makefile.dependencies
diff --git a/kmodload.tproj/Makefile.postamble b/kmodload.tproj/Makefile.postamble
deleted file mode 100644
index b5254fc..0000000
--- a/kmodload.tproj/Makefile.postamble
+++ /dev/null
@@ -1,110 +0,0 @@
-###############################################################################
-#  Makefile.postamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile, which is imported after all other makefiles, to
-#  override attributes for a project's Makefile environment. This allows you  
-#  to take advantage of the environment set up by the other Makefiles. 
-#  You can also define custom rules at the end of this file.
-#
-###############################################################################
-# 
-# These variables are exported by the standard makefiles and can be 
-# used in any customizations you make.  They are *outputs* of
-# the Makefiles and should be used, not set.
-# 
-#  PRODUCTS: products to install.  All of these products will be placed in
-#	 the directory $(DSTROOT)$(INSTALLDIR)
-#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
-#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
-#  OFILE_DIR: Directory into which .o object files are generated.
-#  DERIVED_SRC_DIR: Directory used for all other derived files
-#
-#  ALL_CFLAGS:  flags to pass when compiling .c files
-#  ALL_MFLAGS:  flags to pass when compiling .m files
-#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
-#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
-#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
-#  ALL_LDFLAGS:  flags to pass when linking object files
-#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
-#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
-#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
-#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
-#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
-#
-#  NAME: name of application, bundle, subproject, palette, etc.
-#  LANGUAGES: langages in which the project is written (default "English")
-#  English_RESOURCES: localized resources (e.g. nib's, images) of project
-#  GLOBAL_RESOURCES: non-localized resources of project
-#
-#  SRCROOT:  base directory in which to place the new source files
-#  SRCPATH:  relative path from SRCROOT to present subdirectory
-#
-#  INSTALLDIR: Directory the product will be installed into by 'install' target
-#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
-#        to prefix this with DSTROOT when you use it.
-#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
-#	 to prefix this with DSTROOT when you use it.
-#
-#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
-#
-###############################################################################
-
-# Some compiler flags can be overridden here for certain build situations.
-#
-#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
-#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
-#	to -g)
-#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
-#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
-#	to -O)
-#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
-#	to -pg -DPROFILE)
-#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
-#	the include path (defaults to -I.)
-#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
-#	passed to ld/libtool (defaults to nothing)
-
-
-# Library and Framework projects only:
-#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
-#	against the framework will run against the correct version even if
-#	the current version of the framework changes.  You may override this
-#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
-#	development cycle, but be sure to restore it before installing.
-
-
-# Ownership and permissions of files installed by 'install' target
-
-#INSTALL_AS_USER = root
-        # User/group ownership 
-#INSTALL_AS_GROUP = wheel
-        # (probably want to set both of these) 
-#INSTALL_PERMISSIONS =
-        # If set, 'install' chmod's executable to this
-
-
-# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
-# down further with -x or, if they load no bundles, with no options at all).
-
-#STRIPFLAGS = -S
-
-
-#########################################################################
-# Put rules to extend the behavior of the standard Makefiles here.  Include them in
-# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
-#
-# You should avoid redefining things like "install" or "app", as they are
-# owned by the top-level Makefile API and no context has been set up for where 
-# derived files should go.
-#
-
-after_install::
-	-mkdir -p ${DSTROOT}/usr/share/man/man8
-	-rm -f ${DSTROOT}/usr/share/man/man8/kmodload.8
-	cp kmodload.8 ${DSTROOT}/usr/share/man/man8/kmodload.8
-	chmod og-w ${DSTROOT}/usr/share/man/man8/kmodload.8
-	-rm -f ${DSTROOT}/usr/share/man/man8/kmodsyms.8
-	cp kmodsyms.8 ${DSTROOT}/usr/share/man/man8/kmodsyms.8
-	chmod og-w ${DSTROOT}/usr/share/man/man8/kmodsyms.8
-	$(LN) -f $(INSTALLED_PRODUCTS) $(DSTROOT)/usr/sbin/kmodsyms
diff --git a/kmodload.tproj/Makefile.preamble b/kmodload.tproj/Makefile.preamble
deleted file mode 100644
index c1624b4..0000000
--- a/kmodload.tproj/Makefile.preamble
+++ /dev/null
@@ -1,137 +0,0 @@
-###############################################################################
-#  Makefile.preamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile for configuring the standard application makefiles 
-#  associated with ProjectBuilder. It is included before the main makefile.
-#  In Makefile.preamble you set attributes for a project, so they are available
-#  to the project's makefiles.  In contrast, you typically write additional rules or 
-#  override built-in behavior in the Makefile.postamble.
-#  
-#  Each directory in a project tree (main project plus subprojects) should 
-#  have its own Makefile.preamble and Makefile.postamble.
-###############################################################################
-#
-# Before the main makefile is included for this project, you may set:
-#
-#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
-#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
-
-# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
-# inherited by all nested sub-projects, but the LOCAL_ versions of the same
-# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
-# Build Attributes inspector if at all possible.  To override the default flags
-# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
-# variables below are *inputs* to the build process and distinct from the override
-# settings done (less often) in the Makefile.postamble.
-#
-#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
-#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
-#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
-#	flags in OTHER_MFLAGS, etc.
-#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
-#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
-#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
-#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
-#	precompiling header files
-#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
-#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
-#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
-#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
-#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
-
-# These variables provide hooks enabling you to add behavior at almost every 
-# stage of the make:
-#
-#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
-#    AFTER_PREBUILD: targets to build after installing headers for a subproject
-#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
-#    BEFORE_BUILD: targets to make before a build, but after subprojects
-#    AFTER_BUILD: targets to make after a build
-#
-#    BEFORE_INSTALL: targets to build before installing the product
-#    AFTER_INSTALL: targets to build after installing the product
-#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
-#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
-#
-#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
-#         subproject
-#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
-#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
-#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
-#
-#    BEFORE_DEPEND: targets to build before building dependencies for a
-#	  subproject
-#    AFTER_DEPEND: targets to build after building dependencies for a
-#	  subproject
-#
-#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
-#	  updated every time the project is built.  If NO, the dependency
-#	  file is only built when the depend target is invoked.
-
-# Framework-related variables:
-#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the framework's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-
-# Library-related variables:
-#    PUBLIC_HEADER_DIR:  Determines where public exported header files
-#	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.  For library projects you should
-#       set this to something like /Developer/Headers/$(NAME).  Do not set
-#       this variable for framework projects unless you do not want the
-#       header files included in the framework.
-#    PRIVATE_HEADER_DIR:  Determines where private exported header files
-#  	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.
-#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
-#  	whether the libraries produced are statically linked when they
-#	are used or if they are dynamically loadable. This defaults to
-#       DYNAMIC.
-#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the library's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-#
-#    INSTALL_AS_USER: owner of the intalled products (default root)
-#    INSTALL_AS_GROUP: group of the installed products (default wheel)
-#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
-#
-#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
-#  	passed on the command line to recursive invocations of make.  Note that
-#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
-#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
-#	OTHER_RECURSIVE_VARIABLES. 
-
-# Additional headers to export beyond those in the PB.project:
-#    OTHER_PUBLIC_HEADERS
-#    OTHER_PROJECT_HEADERS
-#    OTHER_PRIVATE_HEADERS
-
-# Additional files for the project's product: <<path relative to proj?>>
-#    OTHER_RESOURCES: (non-localized) resources for this project
-#    OTHER_OFILES: relocatables to be linked into this project
-#    OTHER_LIBS: more libraries to link against
-#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
-#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
-#    OTHER_GARBAGE: additional files to be removed by `make clean'
-
-# Set this to YES if you don't want a final libtool call for a library/framework.
-#    BUILD_OFILES_LIST_ONLY
-
-# To include a version string, project source must exist in a directory named 
-# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
-# OTHER_GENERATED_OFILES = $(VERS_OFILE)
-
-# This definition will suppress stripping of debug symbols when an executable
-# is installed.  By default it is YES.
-# STRIP_ON_INSTALL = NO
-
-# Uncomment to suppress generation of a KeyValueCoding index when installing 
-# frameworks (This index is used by WOB and IB to determine keys available
-# for an object).  Set to YES by default.
-# PREINDEX_FRAMEWORK = NO
-
-# Change this definition to install projects somewhere other than the
-# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
-# and "" on other systems.
-DSTROOT = $(HOME)
diff --git a/kmodload.tproj/PB.project b/kmodload.tproj/PB.project
deleted file mode 100644
index 474d5fe..0000000
--- a/kmodload.tproj/PB.project
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-    DYNAMIC_CODE_GEN = YES; 
-    FILESTABLE = {
-        FRAMEWORKS = (); 
-        HEADERSEARCH = (); 
-        H_FILES = (kld_patch.h); 
-        OTHER_LIBS = (kld); 
-        OTHER_LINKED = (kld_patch.c, kmodload.c); 
-        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, kmodload.8, kmodsyms.8); 
-    }; 
-    LANGUAGE = English; 
-    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
-    NEXTSTEP_BUILDTOOL = /usr/bin/gnumake; 
-    NEXTSTEP_INSTALLDIR = /sbin; 
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
-    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
-    PDO_UNIX_INSTALLDIR = /bin; 
-    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
-    PROJECTNAME = kmodload; 
-    PROJECTTYPE = Tool; 
-    PROJECTVERSION = 2.8; 
-    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
-    WINDOWS_INSTALLDIR = /Library/Executables; 
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
-}
diff --git a/kmodload.tproj/kld_patch.c b/kmodload.tproj/kld_patch.c
deleted file mode 100644
index 646bf14..0000000
--- a/kmodload.tproj/kld_patch.c
+++ /dev/null
@@ -1,2124 +0,0 @@
-/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * History:
- *  2001-05-30 	gvdl	Initial implementation of the vtable patcher.
- */
-// 45678901234567890123456789012345678901234567890123456789012345678901234567890
-
-#include <mach-o/fat.h>
-#include <mach-o/loader.h>
-#include <mach-o/nlist.h>
-#include <mach-o/reloc.h>
-
-#if KERNEL
-
-#include <stdarg.h>
-#include <string.h>
-
-#include <sys/systm.h>
-
-#include <libkern/OSTypes.h>
-
-#include <libsa/stdlib.h>
-#include <libsa/mach/mach.h>
-
-#include "mach_loader.h"
-
-#include <vm/vm_kern.h>
-
-enum { false = 0, true = 1 };
-
-#define vm_page_size page_size
-
-extern load_return_t fatfile_getarch(
-    void            * vp,       // normally a (struct vnode *)
-    vm_offset_t       data_ptr,
-    struct fat_arch * archret);
-
-#else /* !KERNEL */
-#include <unistd.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/errno.h> 
-#include <sys/fcntl.h>
-#include <sys/stat.h>   
-#include <sys/mman.h>   
-
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-
-#include <mach-o/arch.h>
-
-#include <CoreFoundation/CoreFoundation.h>
- 
-#endif /* KERNEL */
-
-#include "kld_patch.h"
-
-#if 0
-static __inline__ void DIE(void) { IODelay(2000000000); }
-
-#define LOG_DELAY()	IODelay(200000)
-#define DEBUG_LOG(x)	do { IOLog x; LOG_DELAY(); } while(0)
-#else
-
-#define DIE()
-#define LOG_DELAY()
-#define DEBUG_LOG(x)
-
-#endif
-
-// OSObject symbol prefixes and suffixes
-#define kVTablePrefix		"___vt"
-#define kReservedPrefix		"__RESERVED"
-#define kSuperClassSuffix	".superClass"
-#define kGMetaSuffix		".gMetaClass"
-#define kLinkEditSegName	SEG_LINKEDIT
-
-// GCC 2.95 drops 2 leading constants in the vtable
-#define kVTablePreambleLen 2
-
-// Last address that I'm willing to try find vm in
-#define kTopAddr  ((unsigned char *) (1024 * 1024 * 1024))
-
-// Size in bytes that Data Ref object's get increased in size
-// Must be a power of 2
-#define kDataCapacityIncrement 128
-
-// My usual set of helper macros.  I personally find these macros
-// easier to read in the code rather than an explicit error condition
-// check.  If I don't make it easy then I may get lazy ond not check
-// everything.  I'm sorry if you find this code harder to read.
-
-// break_if will evaluate the expression and if it is true
-// then it will print the msg, which is enclosed in parens
-// and then break.  Usually used in loops are do { } while (0)
-#define break_if(expr, msg) 					\
-    if (expr) {							\
-	errprintf msg;						\
-        break;							\
-    }
-
-// return_if will evaluate expr and if true it will log the
-// msg, which is enclosed in parens, and then it will return
-// with the return code of ret.
-#define return_if(expr, ret, msg) do {				\
-    if (expr) {							\
-	errprintf msg;						\
-        return ret;						\
-    }								\
-} while (0)
-
-#ifndef MIN
-#define	MIN(a,b) (((a)<(b))?(a):(b))
-#endif /* MIN */
-#ifndef MAX
-#define	MAX(a,b) (((a)>(b))?(a):(b))
-#endif /* MAX */
-
-typedef struct Data {
-    unsigned long fLength, fCapacity;
-    unsigned char *fData;
-} Data, *DataRef;
-
-struct sectionRecord {
-    const struct section *fSection;
-    DataRef fRelocCache;
-};
-
-enum patchState {
-    kSymbolIdentical,
-    kSymbolLocal,
-    kSymbolPadUpdate,
-    kSymbolSuperUpdate,
-    kSymbolMismatch
-};
-
-struct patchRecord {
-    struct nlist *fSymbol;
-    enum patchState fType;
-};
-
-struct relocRecord {
-    void *fValue;
-    const struct nlist *fSymbol;
-    struct relocation_info *fRInfo;
-    void *reserved;
-};
-
-struct metaClassRecord {
-    char *fSuperName;
-    struct fileRecord *fFile;
-    const struct nlist *fVTableSym;
-    struct patchRecord *fPatchedVTable;
-    char fClassName[1];
-};
-
-struct fileRecord {
-    size_t fMapSize, fMachOSize;
-    const char *fPath;
-    unsigned char *fMap, *fMachO, *fPadEnd;
-    DataRef fClassList;
-    DataRef fSectData;
-    DataRef fNewSymbols, fNewStrings;
-    struct symtab_command *fSymtab;
-    struct sectionRecord *fSections;
-    char *fStringBase;
-    struct nlist *fSymbolBase;
-    const struct nlist *fLocalSyms;
-    unsigned int fNSects;
-    int fNLocal;
-    int fNewStringsLen;
-    Boolean fIsKernel, fNoKernelExecutable, fIsKmem;
-    Boolean fImageDirty, fSymbolsDirty;
-};
-
-static DataRef sFilesTable;
-static struct fileRecord *sKernelFile;
-
-static DataRef sMergedFiles;
-static DataRef sMergeMetaClasses;
-static Boolean sMergedKernel;
-
-static void errprintf(const char *fmt, ...)
-{
-    extern void kld_error_vprintf(const char *format, va_list ap);
-
-    va_list ap;
-
-    va_start(ap, fmt);
-    kld_error_vprintf(fmt, ap);
-    va_end(ap);
-
-DIE();
-}
-
-static __inline__ unsigned long DataGetLength(DataRef data)
-{
-    return data->fLength;
-}
-
-static __inline__ unsigned char *DataGetPtr(DataRef data)
-{
-    return data->fData;
-}
-
-
-static __inline__ Boolean DataContainsAddr(DataRef data, void *vAddr)
-{
-    unsigned char *addr = vAddr;
-
-    return (data->fData <= addr) && (addr < data->fData + data->fLength);
-}
-
-static __inline__ Boolean DataAddLength(DataRef data, unsigned long length)
-{
-    static Boolean DataSetLength(DataRef data, unsigned long length);
-    return DataSetLength(data, data->fLength + length);
-}
-
-static __inline__ Boolean
-DataAppendBytes(DataRef data, const void *addr, unsigned int len)
-{
-    unsigned long size = DataGetLength(data);
-
-    if (!DataAddLength(data, len))
-	return false;
-
-    bcopy(addr, DataGetPtr(data) + size, len);
-    return true;
-}
-
-static __inline__ Boolean DataAppendData(DataRef dst, DataRef src)
-{
-    return DataAppendBytes(dst, DataGetPtr(src), DataGetLength(src));
-}
-
-static Boolean DataSetLength(DataRef data, unsigned long length)
-{
-    // Don't bother to ever shrink a data object.
-    if (length > data->fCapacity) {
-	unsigned char *newData;
-	unsigned long newCapacity;
-
-	newCapacity  = length + kDataCapacityIncrement - 1;
-	newCapacity &= ~(kDataCapacityIncrement - 1);
-	newData = (unsigned char *) realloc(data->fData, newCapacity);
-	if (!newData)
-	    return false;
-
-	bzero(newData + data->fCapacity, newCapacity - data->fCapacity);
-	data->fData = newData;
-	data->fCapacity = newCapacity;
-    }
-
-    data->fLength = length;
-    return true;
-}
-
-static DataRef DataCreate(unsigned long length)
-{
-    DataRef data = (DataRef) malloc(sizeof(Data));
-
-    if (data) {
-	if (!length)
-	    data->fCapacity = kDataCapacityIncrement;
-	else {
-	    data->fCapacity  = length + kDataCapacityIncrement - 1;
-	    data->fCapacity &= ~(kDataCapacityIncrement - 1);
-	}
-
-	data->fData = (unsigned char *) malloc(data->fCapacity);
-	if (!data->fData) {
-	    free(data);
-	    return NULL;
-	}
-
-	bzero(data->fData, data->fCapacity);
-	data->fLength = length;
-    }
-    return data;
-}
-
-static void DataRelease(DataRef data)
-{
-    if (data) {
-	if (data->fData)
-	    free(data->fData);
-	data->fData = 0;
-	free(data);
-    }
-}
-
-static const char *
-symbolname(const struct fileRecord *file, const struct nlist *sym)
-{
-    unsigned long strsize;
-    long strx = sym->n_un.n_strx;
-
-    if (strx >= 0)
-	return file->fStringBase + strx;
-
-    strsize = file->fSymtab->strsize;
-    strx = -strx;
-    if (strx < strsize)
-	return file->fStringBase + strx;
-
-    strx -= strsize;
-    return (char *) DataGetPtr(file->fNewStrings) + strx;
-}
-
-static struct fileRecord *getFile(const char *path)
-{
-    if (sFilesTable) {
-	int i, nfiles;
-	struct fileRecord **files;
-
-        // Check to see if we have already merged this file
-	nfiles = DataGetLength(sFilesTable) / sizeof(struct fileRecord *);
-	files = (struct fileRecord **) DataGetPtr(sFilesTable);
-	for (i = 0; i < nfiles; i++) {
-	    if (!strcmp(path, files[i]->fPath))
-		return files[i];
-	}
-    }
-
-    return NULL;
-}
-
-static struct fileRecord * addFile(struct fileRecord *file)
-{
-    struct fileRecord *newFile;
-
-    if (!sFilesTable) {
-	sFilesTable = DataCreate(0);
-	if (!sFilesTable)
-	    return NULL;
-    }
-
-    newFile = (struct fileRecord *) malloc(sizeof(struct fileRecord));
-    if (!newFile)
-	return NULL;
-
-    if (!DataAppendBytes(sFilesTable, &newFile, sizeof(newFile))) {
-	free(newFile);
-	return NULL;
-    }
-
-    bcopy(file, newFile, sizeof(struct fileRecord));
-    return newFile;
-}
-
-// @@@ gvdl: need to clean up the sMergeMetaClasses
-// @@@ gvdl: I had better fix the object file up again
-static void removeFile(struct fileRecord *file)
-{
-    if (file->fClassList) {
-	DataRelease(file->fClassList);
-	file->fClassList = 0;
-    }
-
-    if (file->fSectData) {
-	struct sectionRecord *section;
-	unsigned int i, nsect;
-
-	nsect = file->fNSects;
-	section = file->fSections;
-	for (i = 0; i < nsect; i++, section++) {
-	    if (section->fRelocCache) {
-		DataRelease(section->fRelocCache);
-		section->fRelocCache = 0;
-	    }
-	}
-
-	DataRelease(file->fSectData);
-	file->fSectData = 0;
-	file->fSections = 0;
-	file->fNSects = 0;
-    }
-
-    if (file->fMap) {
-#if KERNEL
-	if (file->fIsKmem)
-	    kmem_free(kernel_map, (vm_address_t) file->fMap, file->fMapSize);
-#else /* !KERNEL */
-	if (file->fPadEnd) {
-	    vm_address_t padVM;
-	    vm_size_t padSize;
-
-	    padVM = round_page((vm_address_t) file->fMap + file->fMapSize);
-	    padSize  = (vm_size_t) ((vm_address_t) file->fPadEnd - padVM);
-	    (void) vm_deallocate(mach_task_self(), padVM, padSize);
-	    file->fPadEnd = 0;
-	}
-
-	(void) munmap((caddr_t) file->fMap, file->fMapSize);
-#endif /* !KERNEL */
-	file->fMap = 0;
-    }
-
-    file->fPath = 0;
-}
-
-#if !KERNEL
-static Boolean
-mapObjectFile(struct fileRecord *file)
-{
-    Boolean result = false;
-    static unsigned char *sFileMapBaseAddr;
-
-    int fd = 0;
-
-    if (!sFileMapBaseAddr) {
-        kern_return_t ret;
-	vm_address_t probeAddr;
-
-	// If we don't already have a base addr find any random chunk
-	// of 32 meg of VM and to use the 16 meg boundrary as a base.
-        ret = vm_allocate(mach_task_self(), &probeAddr,
-			    32 * 1024 * 1024, VM_FLAGS_ANYWHERE);
-	return_if(KERN_SUCCESS != ret, false,
-	    ("Unable to allocate base memory %s\n", mach_error_string(ret)));
-        (void) vm_deallocate(mach_task_self(), probeAddr, 32 * 1024 * 1024);
-
-	// Now round to the next 16 Meg boundrary
-	probeAddr = (probeAddr +  (16 * 1024 * 1024 - 1))
-		               & ~(16 * 1024 * 1024 - 1);
-	sFileMapBaseAddr = (unsigned char *) probeAddr;
-    }
-
-    fd = open(file->fPath, O_RDONLY, 0);
-    return_if(fd == -1, false, ("Can't open %s for reading - %s\n",
-	file->fPath, strerror(errno)));
-
-    do {
-	kern_return_t ret;
-	struct stat sb;
-	int retaddr = -1;
-
-	break_if(fstat(fd, &sb) == -1,
-	    ("Can't stat %s - %s\n", file->fPath, strerror(errno)));
-
-	file->fMapSize = sb.st_size;
-	file->fMap = sFileMapBaseAddr;
-	ret = KERN_SUCCESS;
-	while (file->fMap < kTopAddr) {
-	    vm_address_t padVM;
-	    vm_address_t padVMEnd;
-	    vm_size_t padSize;
-
-	    padVM = round_page((vm_address_t) file->fMap + file->fMapSize);
-	    retaddr = (int) mmap(file->fMap, file->fMapSize,
-				 PROT_READ|PROT_WRITE, 
-				 MAP_FIXED|MAP_FILE|MAP_PRIVATE,
-				 fd, 0);
-	    if (-1 == retaddr) {
-		break_if(ENOMEM != errno,
-		    ("mmap failed %d - %s\n", errno, strerror(errno)));
-
-		file->fMap = (unsigned char *) padVM;
-		continue;
-	    }
-
-
-	    // Round up padVM to the next page after the file and assign at
-	    // least another fMapSize more room rounded up to the next page
-	    // boundary.
-	    padVMEnd = round_page(padVM + file->fMapSize);
-	    padSize  = padVMEnd - padVM;
-	    ret = vm_allocate(
-		mach_task_self(), &padVM, padSize, VM_FLAGS_FIXED);
-	    if (KERN_SUCCESS == ret) {
-		file->fPadEnd = (unsigned char *) padVMEnd;
-		break;
-	    }
-	    else {
-		munmap(file->fMap, file->fMapSize);
-		break_if(KERN_INVALID_ADDRESS != ret,
-		    ("Unable to allocate pad vm for %s - %s\n",
-			file->fPath, mach_error_string(ret)));
-
-		file->fMap = (unsigned char *) padVMEnd;
-		continue; // try again wherever the vm system wants
-	    }
-	}
-
-	if (-1 == retaddr || KERN_SUCCESS != ret)
-	    break;
-
-	break_if(file->fMap >= kTopAddr,
-	    ("Unable to map memory %s\n", file->fPath));
-
-	sFileMapBaseAddr = file->fPadEnd;
-	result = true;
-    } while(0);
-
-    close(fd);
-    return result;
-}
-#endif /* !KERNEL */
-
-static Boolean findBestArch(struct fileRecord *file)
-{
-    unsigned long magic;
-    struct fat_header *fat;
-
-
-    file->fMachOSize = file->fMapSize;
-    file->fMachO = file->fMap;
-    magic = ((const struct mach_header *) file->fMachO)->magic;
-    fat = (struct fat_header *) file->fMachO;
-
-    // Try to figure out what type of file this is
-    return_if(file->fMapSize < sizeof(unsigned long), false,
-	("%s isn't a valid object file - no magic\n", file->fPath));
-
-#if KERNEL
-
-    // CIGAM is byte-swapped MAGIC
-    if (magic == FAT_MAGIC || magic == FAT_CIGAM) {
-
-        load_return_t load_return;
-        struct fat_arch fatinfo;
-
-        load_return = fatfile_getarch(NULL, (vm_address_t) fat, &fatinfo);
-	return_if(load_return != LOAD_SUCCESS, false,
-	    ("Extension \"%s\": has no code for this computer\n", file->fPath));
-
-	file->fMachO = file->fMap + fatinfo.offset;
-	file->fMachOSize = fatinfo.size;
-	magic = ((const struct mach_header *) file->fMachO)->magic;
-    }
-
-#else /* !KERNEL */
-
-    // Do we need to in-place swap the endianness of the fat header?
-    if (magic == FAT_CIGAM) {
-	unsigned long i;
-	struct fat_arch *arch;
-
-	fat->nfat_arch = NXSwapBigLongToHost(fat->nfat_arch);
-	return_if(file->fMapSize < sizeof(struct fat_header)
-				    + fat->nfat_arch * sizeof(struct fat_arch),
-	    false, ("%s is too fat\n", file->fPath));
-
-	arch = (struct fat_arch *) &fat[1];
-	for (i = 0; i < fat->nfat_arch; i++) {
-	    arch[i].cputype    = NXSwapBigLongToHost(arch[i].cputype);
-	    arch[i].cpusubtype = NXSwapBigLongToHost(arch[i].cpusubtype);
-	    arch[i].offset     = NXSwapBigLongToHost(arch[i].offset);
-	    arch[i].size       = NXSwapBigLongToHost(arch[i].size);
-	    arch[i].align      = NXSwapBigLongToHost(arch[i].align);
-	}
-
-	magic = NXSwapBigLongToHost(fat->magic);
-    }
-
-    // Now see if we can find any valid architectures
-    if (magic == FAT_MAGIC) {
-	const NXArchInfo *myArch;
-	unsigned long fatsize;
-	struct fat_arch *arch;
-
-	fatsize = sizeof(struct fat_header)
-	    + fat->nfat_arch * sizeof(struct fat_arch);
-	return_if(file->fMapSize < fatsize,
-	    false, ("%s isn't a valid fat file\n", file->fPath));
-
-	myArch = NXGetLocalArchInfo();
-	arch = NXFindBestFatArch(myArch->cputype, myArch->cpusubtype,
-		(struct fat_arch *) &fat[1], fat->nfat_arch);
-	return_if(!arch,
-	    false, ("%s hasn't got arch for %s\n", file->fPath, myArch->name));
-	return_if(arch->offset + arch->size > file->fMapSize,
-	    false, ("%s's %s arch is incomplete\n", file->fPath, myArch->name));
-	file->fMachO = file->fMap + arch->offset;
-	file->fMachOSize = arch->size;
-	magic = ((const struct mach_header *) file->fMachO)->magic;
-    }
-
-#endif /* KERNEL */
-
-    return_if(magic != MH_MAGIC,
-	false, ("%s isn't a valid mach-o\n", file->fPath));
-
-    return true;
-}
-
-static Boolean
-parseSegments(struct fileRecord *file, struct segment_command *seg)
-{
-    struct sectionRecord *sections;
-    int i, nsects = seg->nsects;
-    const struct segmentMap {
-	struct segment_command seg;
-	const struct section sect[1];
-    } *segMap;
-
-    if (!nsects) {
-#if KERNEL
-	// We don't need to look for the LinkEdit segment unless
-	// we are running in the kernel environment.
-	if (!strcmp(kLinkEditSegName, seg->segname)) {
-	    // Grab symbol table from linkedit we will need this later
-	    file->fSymbolBase = (void *) seg;
-	}
-#endif
-
-	return true; 	// Nothing more to do, so that was easy.
-    }
-
-    if (!file->fSectData) {
-	file->fSectData = DataCreate(0);
-	if (!file->fSectData)
-	    return false;
-    }
-
-    // Increase length of section DataRef and cache data pointer
-    if (!DataAddLength(file->fSectData, nsects * sizeof(struct sectionRecord)))
-	return false;
-    file->fSections = (struct sectionRecord *) DataGetPtr(file->fSectData);
-
-    // Initialise the new sections
-    sections = &file->fSections[file->fNSects];
-    file->fNSects += nsects;
-    for (i = 0, segMap = (struct segmentMap *) seg; i < nsects; i++)
-	sections[i].fSection = &segMap->sect[i];
-
-    return true;
-}
-
-// @@@ gvdl:  These functions need to be hashed they are
-// going to be way too slow for production code.
-static const struct nlist *
-findSymbolByAddress(const struct fileRecord *file, void *entry)
-{
-    // not quite so dumb linear search of all symbols
-    const struct nlist *sym;
-    int i, nsyms;
-
-    // First try to find the symbol in the most likely place which is the
-    // extern symbols
-    sym = file->fLocalSyms;
-    for (i = 0, nsyms = file->fNLocal; i < nsyms; i++, sym++) {
-	if (sym->n_value == (unsigned long) entry && !(sym->n_type & N_STAB) )
-	    return sym;
-    }
-
-    // Didn't find it in the external symbols so try to local symbols before
-    // giving up.
-    sym = file->fSymbolBase;
-    for (i = 0, nsyms = file->fSymtab->nsyms; i < nsyms; i++, sym++) {
-	if ( (sym->n_type & N_EXT) )
-	    return NULL;
-	if ( sym->n_value == (unsigned long) entry && !(sym->n_type & N_STAB) )
-	    return sym;
-    }
-
-    return NULL;
-}
-
-struct searchContext {
-    const char *fSymname;
-    const char *fStrbase;
-};
-
-static int symbolSearch(const void *vKey, const void *vSym)
-{
-    const struct searchContext *key = (const struct searchContext *) vKey;
-    const struct nlist *sym = (const struct nlist *) vSym;
-
-    return strcmp(key->fSymname, key->fStrbase + sym->n_un.n_strx);
-}
-
-static const struct nlist *
-findSymbolByName(struct fileRecord *file, const char *symname)
-{
-    struct searchContext context;
-
-    context.fSymname = symname;
-    context.fStrbase = file->fStringBase;
-    return (struct nlist *)
-	bsearch(&context,
-		file->fLocalSyms, file->fNLocal, sizeof(struct nlist),
-		symbolSearch);
-}
-
-static Boolean
-relocateSection(const struct fileRecord *file, struct sectionRecord *sectionRec)
-{
-    const struct nlist *symbol;
-    const struct section *section;
-    struct relocRecord *rec;
-    struct relocation_info *rinfo;
-    unsigned long i;
-    unsigned long r_address, r_symbolnum, r_length;
-    enum reloc_type_generic r_type;
-    UInt8 *sectionBase;
-    void **entry;
-
-    sectionRec->fRelocCache = DataCreate(
-	sectionRec->fSection->nreloc * sizeof(struct relocRecord));
-    if (!sectionRec->fRelocCache)
-	return false;
-
-    section = sectionRec->fSection;
-    sectionBase = file->fMachO + section->offset;
-
-    rec = (struct relocRecord *) DataGetPtr(sectionRec->fRelocCache);
-    rinfo = (struct relocation_info *) (file->fMachO + section->reloff);
-    for (i = 0; i < section->nreloc; i++, rec++, rinfo++) {
-
-	// Totally uninterested in scattered relocation entries
-	if ( (rinfo->r_address & R_SCATTERED) )
-	    continue;
-
-	r_address = rinfo->r_address;
-	entry = (void **) (sectionBase + r_address);
-
-	/*
-	 * The r_address field is really an offset into the contents of the
-	 * section and must reference something inside the section (Note
-	 * that this is not the case for PPC_RELOC_PAIR entries but this
-	 * can't be one with the above checks).
-	 */
-	return_if(r_address >= section->size, false,
-	    ("Invalid relocation entry in %s - not in section\n", file->fPath));
-
-	// If we don't have a VANILLA entry or the Vanilla entry isn't
-	// a 'long' then ignore the entry and try the next.
-	r_type = (enum reloc_type_generic) rinfo->r_type;
-	r_length = rinfo->r_length;
-	if (r_type != GENERIC_RELOC_VANILLA || r_length != 2)
-	    continue;
-
-	r_symbolnum = rinfo->r_symbolnum;
-
-	/*
-	 * If rinfo->r_extern is set this relocation entry is an external entry
-	 * else it is a local entry.
-	 */
-	if (rinfo->r_extern) {
-	    /*
-	     * This is an external relocation entry.
-	     * r_symbolnum is an index into the input file's symbol table
-	     * of the symbol being refered to.  The symbol must be
-	     * undefined to be used in an external relocation entry.
-	     */
-	    return_if(r_symbolnum >= file->fSymtab->nsyms, false, 
-		("Invalid relocation entry in %s - no symbol\n", file->fPath));
-
-	    /*
-	     * If this is an indirect symbol resolve indirection (all chains
-	     * of indirect symbols have been resolved so that they point at
-	     * a symbol that is not an indirect symbol).
-	     */
-	    symbol = file->fSymbolBase;
-	    if ((symbol[r_symbolnum].n_type & N_TYPE) == N_INDR)
-		r_symbolnum = symbol[r_symbolnum].n_value;
-	    symbol = &symbol[r_symbolnum];
-
-	    return_if(symbol->n_type != (N_EXT | N_UNDF), false, 
-		("Invalid relocation entry in %s - extern\n", file->fPath));
-	}
-	else {
-	    /*
-	     * If the symbol is not in any section then it can't be a
-	     * pointer to a local segment and I don't care about it.
-	     */
-	    if (r_symbolnum == R_ABS)
-		continue;
-
-	    // Note segment references are offset by 1 from 0.
-	    return_if(r_symbolnum > file->fNSects, false,
-		("Invalid relocation entry in %s - local\n", file->fPath));
-
-	    // Find the symbol, if any, that backs this entry 
-	    symbol = findSymbolByAddress(file, *entry);
-	}
-
-	rec->fValue  = *entry;		// Save the previous value
-	rec->fRInfo  =  rinfo;		// Save a pointer to the reloc
-	rec->fSymbol =  symbol;		// Record the current symbol
-
-	*entry = (void *) rec;	// Save pointer to record in object image
-    }
-
-    ((struct fileRecord *) file)->fImageDirty = true;
-
-    return true;
-}
-
-static const struct nlist *
-findSymbolRefAtLocation(const struct fileRecord *file,
-			struct sectionRecord *sctn, void **loc)
-{
-    if (file->fIsKernel) {
-	if (*loc)
-	    return findSymbolByAddress(file, *loc);
-    }
-    else if (sctn->fRelocCache || relocateSection(file, sctn)) {
-	struct relocRecord *reloc = (struct relocRecord *) *loc;
-
-	if (DataContainsAddr(sctn->fRelocCache, reloc))
-	    return reloc->fSymbol;
-    }
-
-    return NULL;
-}
-
-static Boolean
-addClass(struct fileRecord *file,
-	 struct metaClassRecord *inClass,
-	 const char *cname)
-{
-    struct metaClassRecord *newClass = NULL;
-    struct metaClassRecord **fileClasses = NULL;
-    int len;
-
-if (!file->fIsKernel) {	// @@@ gvdl:
-    DEBUG_LOG(("Adding Class %s\n", cname));
-}
-
-    if (!file->fClassList) {
-	file->fClassList = DataCreate(0);
-	if (!file->fClassList)
-	    return false;
-    }
-
-    do {
-	// Attempt to allocate all necessary resource first
-	len = strlen(cname) + 1
-	    + (int) (&((struct metaClassRecord *) 0)->fClassName);
-	newClass = (struct metaClassRecord *) malloc(len);
-	if (!newClass)
-	    break;
-
-	if (!DataAddLength(file->fClassList, sizeof(struct metaClassRecord *)))
-	    break;
-	fileClasses = (struct metaClassRecord **)
-	    (DataGetPtr(file->fClassList) + DataGetLength(file->fClassList));
-
-	// Copy the meta Class structure and string name into newClass
-	// and insert object at end of the file->fClassList and sMergeMetaClasses 
-	*newClass = *inClass;
-	strcpy(newClass->fClassName, cname);
-	fileClasses[-1]   = newClass;
-
-	return true;
-    } while (0);
-
-    if (fileClasses)
-	DataAddLength(file->fClassList, -sizeof(struct metaClassRecord *));
-
-    if (newClass)
-	free(newClass);
-
-    return false;
-}
-
-static struct metaClassRecord *getClass(DataRef classList, const char *cname)
-{
-    if (classList) {
-	int i, nclass;
-	struct metaClassRecord **classes, *thisClass;
-    
-	nclass = DataGetLength(classList) / sizeof(struct metaClassRecord *);
-	classes = (struct metaClassRecord **) DataGetPtr(classList);
-	for (i = 0; i < nclass; i++) {
-	    thisClass = classes[i];
-	    if (!strcmp(thisClass->fClassName, cname))
-		return thisClass;
-	}
-    }
-
-    return NULL;
-}
-
-// Add the class 'cname' to the list of known OSObject based classes
-// Note 'sym' is the <cname>.superClass symbol. 
-static Boolean
-recordClass(struct fileRecord *file, const char *cname, const struct nlist *sym)
-{
-    char *supername = NULL;
-    const char *classname = NULL;
-    struct metaClassRecord newClass;
-    char strbuffer[1024];
-
-    // Only do the work actual work to find the super class if we are
-    // not currently working on  the kernel.  The kernel is the end
-    // of all superclass chains as by definition the kernel is binary
-    // compatible with itself.
-    if (!file->fIsKernel) {
-	const char *dot;
-	const struct nlist *supersym;
-	const struct section *section;
-	struct sectionRecord *sectionRec;
-	unsigned char sectind = sym->n_sect;
-	const char *superstr;
-	void **location;
-
-	// We can't resolve anything that isn't in a real section
-	// Note that the sectind is starts at one to make room for the
-	// NO_SECT flag but the fNSects field isn't offset so we have a
-	// '>' test.  Which means this isn't an OSObject based class
-	if (sectind == NO_SECT || sectind > file->fNSects)
-	    return true;
-    
-	sectionRec = file->fSections + sectind - 1;
-	section = sectionRec->fSection;
-	location = (void **) ( file->fMachO + section->offset
-			    + sym->n_value - section->addr );
-    
-	supersym = findSymbolRefAtLocation(file, sectionRec, location);
-	if (!supersym)
-	    return true;	// No superclass symbol then it isn't an OSObject.
-
-	// Find string in file and skip leading '_' and find last '.'
-	superstr = symbolname(file, supersym) + 1;
-	dot = strrchr(superstr, '.');
-	if (!dot || strcmp(dot, kGMetaSuffix))
-	    return true;	// Not an OSObject superclass so ignore it.
-
-	supername = (char *) malloc(dot - superstr + 1);
-	strncpy(supername, superstr, dot - superstr);
-	supername[dot - superstr] = '\0';
-    }
-
-    do {
-	break_if(getClass(file->fClassList, cname),
-	    ("Duplicate class %s in %s\n", cname, file->fPath));
-    
-	snprintf(strbuffer, sizeof(strbuffer), "%s%s", kVTablePrefix, cname);
-	newClass.fVTableSym = findSymbolByName(file, strbuffer);
-	break_if(!newClass.fVTableSym,
-	    ("Can't find vtable %s in %s\n", cname, file->fPath));
-
-	newClass.fFile = file;
-	newClass.fSuperName = supername;
-	newClass.fPatchedVTable = NULL;
-    
-	// Can't use cname as it may be a stack variable
-	// However the vtable's string has the class name as a suffix
-	// so why don't we use that rather than mallocing a string.
-	classname = symbolname(file, newClass.fVTableSym)
-		+ sizeof(kVTablePrefix) - 1;
-	break_if(!addClass(file, &newClass, classname), 
-		    ("recordClass - no memory?\n"));
-
-	return true;
-    } while (0);
-    
-    if (supername)
-	free(supername);
-
-    return false;
-}
-
-static Boolean getMetaClassGraph(struct fileRecord *file)
-{
-    const struct nlist *sym;
-    const char *strbase;
-    int i, nsyms;
-
-    // Search the symbol table for the local symbols that are generated
-    // by the metaclass system.  There are three metaclass variables
-    // that are relevant.
-    //
-    //   <ClassName>.metaClass	A pointer to the meta class structure.
-    //	 <ClassName>.superClass	A pointer to the super class's meta class.
-    //	 <ClassName>.gMetaClass	The meta class structure itself.
-    //	 ___vt<ClassName>	The VTable for the class <ClassName>.
-    //
-    // In this code I'm going to search for any symbols that
-    // ends in kSuperClassSuffix as this indicates this class is a conforming
-    // OSObject subclass and will need to be patched, and it also
-    // contains a pointer to the super class's meta class structure.
-    strbase = file->fStringBase;
-    sym = file->fLocalSyms;
-    for (i = 0, nsyms = file->fNLocal; i < nsyms; i++, sym++) {
-	const char *symname;
-	const char *dot;
-	char classname[1024];
-	unsigned char n_type = sym->n_type & (N_TYPE | N_EXT);
-
-	// Check that the symbols is a global and that it has a name.
-	if (((N_SECT | N_EXT) != n_type && (N_ABS | N_EXT) != n_type)
-	||  !sym->n_un.n_strx)
-	    continue;
-
-	// Only search from the last '.' in the symbol.
-	// but skip the leading '_' in all symbols first.
-	symname = strbase + sym->n_un.n_strx + 1;
-	dot = strrchr(symname, '.');
-	if (!dot || strcmp(dot, kSuperClassSuffix))
-	    continue;
-
-	// Got a candidate so hand it over for class processing.
-	return_if(dot - symname >= (int) sizeof(classname),
-	    false, ("Symbol %s is too long\n", symname));
-
-	bcopy(symname, classname, dot - symname);
-	classname[dot - symname] = '\0';
-	if (!recordClass(file, classname, sym))
-	    return false;
-    }
-
-    return_if(!file->fClassList, false, ("Internal error, "
-	      "getMetaClassGraph(%s) found no classes", file->fPath)); 
-
-    DEBUG_LOG(("Found %d classes in %x for %s\n",
-	DataGetLength(file->fClassList)/sizeof(void*),
-	file->fClassList, file->fPath));
-
-    return true;
-}
-
-static Boolean mergeOSObjectsForFile(const struct fileRecord *file)
-{
-    int i, nmerged;
-    Boolean foundDuplicates = false;
-
-DEBUG_LOG(("Merging file %s\n", file->fPath));	// @@@ gvdl:
-
-    if (!file->fClassList)
-	return true;
-
-    if (!sMergedFiles) {
-	sMergedFiles = DataCreate(0);
-	return_if(!sMergedFiles, false,
-	    ("Unable to allocate memory metaclass list\n", file->fPath));
-    }
-
-    // Check to see if we have already merged this file
-    nmerged = DataGetLength(sMergedFiles) / sizeof(struct fileRecord *);
-    for (i = 0; i < nmerged; i++) {
-	if (file == ((void **) DataGetPtr(sMergedFiles))[i])
-	    return true;
-    }
-
-    if (!sMergeMetaClasses) {
-	sMergeMetaClasses = DataCreate(0);
-	return_if(!sMergeMetaClasses, false,
-	    ("Unable to allocate memory metaclass list\n", file->fPath));
-    }
-    else {	/* perform a duplicate check */
-	int i, j, cnt1, cnt2;
-	struct metaClassRecord **list1, **list2;
-
-	list1 = (struct metaClassRecord **) DataGetPtr(file->fClassList);
-	cnt1  = DataGetLength(file->fClassList)  / sizeof(*list1);
-	list2 = (struct metaClassRecord **) DataGetPtr(sMergeMetaClasses);
-	cnt2  = DataGetLength(sMergeMetaClasses) / sizeof(*list2);
-
-	for (i = 0; i < cnt1; i++) {
-	    for (j = 0; j < cnt2; j++) {
-		if (!strcmp(list1[i]->fClassName, list2[j]->fClassName)) {
-		    errprintf("duplicate class %s in %s & %s\n",
-			      list1[i]->fClassName,
-			      file->fPath, list2[j]->fFile->fPath);
-		}
-	    }
-	}
-    }
-    if (foundDuplicates)
-	return false;
-
-    return_if(!DataAppendBytes(sMergedFiles, &file, sizeof(file)), false,
-	("Unable to allocate memory to merge %s\n", file->fPath));
-
-    return_if(!DataAppendData(sMergeMetaClasses, file->fClassList), false,
-	("Unable to allocate memory to merge %s\n", file->fPath));
-
-    if (file == sKernelFile)
-	sMergedKernel = true;
-
-    return true;
-}
-
-// Returns a pointer to the base of the section offset by the sections
-// base address.  The offset is so that we can add nlist::n_values directly
-// to this address and get a valid pointer in our memory.
-static unsigned char *
-getSectionForSymbol(const struct fileRecord *file, const struct nlist *symb,
-		    void ***endP)
-{
-    const struct section *section;
-    unsigned char sectind;
-    unsigned char *base;
-
-    sectind = symb->n_sect;	// Default to symbols section
-    if ((symb->n_type & N_TYPE) == N_ABS && file->fIsKernel) {
-	// Absolute symbol so we have to iterate over our sections
-	for (sectind = 1; sectind <= file->fNSects; sectind++) {
-	    unsigned long start, end;
-
-	    section = file->fSections[sectind - 1].fSection;
-	    start = section->addr;
-	    end   = start + section->size;
-	    if (start <= symb->n_value && symb->n_value < end) {
-		// Found the relevant section
-		break;
-	    }
-	}
-    }
-
-    // Is the vtable in a valid section?
-    return_if(sectind == NO_SECT || sectind > file->fNSects,
-	(unsigned char *) -1,
-	("%s isn't a valid kext, bad section reference\n", file->fPath));
-
-    section = file->fSections[sectind - 1].fSection;
-
-    // for when we start walking the vtable so compute offset's now.
-    base = file->fMachO + section->offset;
-    *endP = (void **) (base + section->size);
-
-    return base - section->addr;	// return with addr offset
-}
-
-static Boolean resolveKernelVTable(struct metaClassRecord *metaClass)
-{
-    const struct fileRecord *file;
-    struct patchRecord *patchedVTable;
-    void **curEntry, **vtableEntries, **endSection;
-    unsigned char *sectionBase;
-    struct patchRecord *curPatch;
-    int classSize;
-
-    // Should never occur but it doesn't cost us anything to check.
-    if (metaClass->fPatchedVTable)
-	return true;
-
-DEBUG_LOG(("Kernel vtable %s\n", metaClass->fClassName));	// @@@ gvdl:
-
-    // Do we have a valid vtable to patch?
-    return_if(!metaClass->fVTableSym,
-	false, ("Internal error - no class vtable symbol?\n"));
-
-    file = metaClass->fFile;
-
-    // If the metaClass we are being to ask is in the kernel then we
-    // need to do a quick scan to grab the fPatchList in a reliable format
-    // however we don't need to check the superclass in the kernel
-    // as the kernel vtables are always correct wrt themselves.
-    // Note this ends the superclass chain recursion.
-    return_if(!file->fIsKernel,
-	false, ("Internal error - resolveKernelVTable not kernel\n"));
-
-    if (file->fNoKernelExecutable) {
-	// Oh dear attempt to map the kernel's VM into my memory space
-	return_if(file->fNoKernelExecutable, false,
-	    ("Internal error - fNoKernelExecutable not implemented yet\n"));
-    }
-
-    // We are going to need the base and the end
-    sectionBase = getSectionForSymbol(file, metaClass->fVTableSym, &endSection);
-    if (-1 == (long) sectionBase)
-	return false;
-
-    vtableEntries  = (void **) (sectionBase + metaClass->fVTableSym->n_value);
-    curEntry = vtableEntries + kVTablePreambleLen;
-    for (classSize = 0; curEntry < endSection && *curEntry; classSize++)
-	curEntry++;
-
-    return_if(*curEntry, false, ("Bad kernel image, short section\n"));
-
-    patchedVTable = (struct patchRecord *)
-	malloc((classSize + 1) * sizeof(struct patchRecord));
-    return_if(!patchedVTable, false, ("resolveKernelVTable - no memory\n"));
-
-    // Copy the vtable of this class into the patch table
-    curPatch = patchedVTable;
-    curEntry = vtableEntries + kVTablePreambleLen;
-    for (; *curEntry; curEntry++, curPatch++) {
-	curPatch->fSymbol = (struct nlist *) 
-	    findSymbolByAddress(file, *curEntry);
-	curPatch->fType = kSymbolLocal;
-    }
-
-    // Tag the end of the patch vtable
-    curPatch->fSymbol = NULL;
-    metaClass->fPatchedVTable = patchedVTable;
-
-    return true;
-}
-
-// reloc->fPatch must contain a valid pointer on entry
-static struct nlist *
-getNewSymbol(struct fileRecord *file,
-	     const struct relocRecord *reloc, const char *supername)
-{
-    unsigned int size, i, namelen;
-    struct nlist **sym;
-    struct nlist *msym;
-    const char *strbase;
-    struct relocation_info *rinfo;
-    long strx;
-
-    if (!file->fNewSymbols) {
-	file->fNewSymbols = DataCreate(0);
-	return_if(!file->fNewSymbols, NULL,
-	    ("Unable to allocate new symbol table for %s\n", file->fPath));
-    }
-
-    // Make sure we have a string table as well for the new symbol
-    if (!file->fNewStrings) {
-	file->fNewStrings = DataCreate(0);
-	return_if(!file->fNewStrings, NULL,
-	    ("Unable to allocate string table for %s\n", file->fPath));
-    }
-
-    rinfo = (struct relocation_info *) reloc->fRInfo;
-    size = DataGetLength(file->fNewSymbols) / sizeof(struct nlist *);
-    sym = (const struct nlist **) DataGetPtr(file->fNewSymbols);
-    // remember that the n_strx for new symbols names is negated
-    strbase = (const char *)
-		DataGetPtr(file->fNewStrings) - file->fSymtab->strsize;
-    for (i = 0; i < size; i++, sym++) {
-        const char *symname = strbase - (*sym)->n_un.n_strx;
-
-	if (!strcmp(symname, supername)) {
-	    rinfo->r_symbolnum = i + file->fSymtab->nsyms;
-	    file->fSymbolsDirty = true; 
-	    return *sym;
-	}
-    }
-
-    // Assert that this is a vaild symbol.  I need this condition to be true
-    // for the later code to make non-zero.  So the first time through I'd 
-    // better make sure that it is 0.
-    return_if(reloc->fSymbol->n_sect, NULL,
-	("Undefined symbol entry with non-zero section %s:%s\n",
-	file->fPath, symbolname(file, reloc->fSymbol)));
-
-    msym = (struct nlist *) malloc(sizeof(struct nlist));
-    return_if(!msym,
-	NULL, ("Unable to create symbol table entry for %s\n", file->fPath));
-
-    // If we are here we didn't find the symbol so create a new one now
-    if (!DataAppendBytes(file->fNewSymbols, &msym, sizeof(msym))) {
-	free(msym);
-	return_if(true,
-	    NULL, ("Unable to grow symbol table for %s\n", file->fPath));
-    }
-
-    namelen = strlen(supername) + 1;
-    strx = DataGetLength(file->fNewStrings);
-    if (!DataAppendBytes(file->fNewStrings, supername, namelen)) {
-	free(msym);
-	DataAddLength(file->fNewSymbols, -sizeof(struct nlist)); // Undo harm
-	return_if(true, NULL,
-		 ("Unable to grow string table for %s\n", file->fPath));
-    }
-
-    // Offset the string index by the original string table size
-    // and negate the address to indicate that this is a 'new' symbol
-    msym->n_un.n_strx = -(strx + file->fSymtab->strsize);
-    msym->n_type = (N_EXT | N_UNDF);
-    msym->n_sect = NO_SECT;
-    msym->n_desc = 0;
-    msym->n_value = 0;
-
-    // Mark the old symbol as being potentially deletable I can use the
-    // n_sect field as the input symbol must be of type N_UNDF which means
-    // that the n_sect field must be set to NO_SECT otherwise it is an
-    // in valid input file.
-    ((struct nlist *) reloc->fSymbol)->n_un.n_strx
-	= -reloc->fSymbol->n_un.n_strx;    
-    ((struct nlist *) reloc->fSymbol)->n_sect = (unsigned char) -1;
-
-    rinfo->r_symbolnum = i + file->fSymtab->nsyms;
-    file->fSymbolsDirty = true; 
-    return msym;
-}
-
-static struct nlist *
-fixOldSymbol(struct fileRecord *file,
-	     const struct relocRecord *reloc, const char *supername)
-{
-    unsigned int namelen;
-    struct nlist *sym = (struct nlist *) reloc->fSymbol;
-    const char *oldname = symbolname(file, sym);
-
-    // assert(sym->n_un.n_strx >= 0);
-
-    namelen = strlen(supername);
-    if (namelen < strlen(oldname)) {
-	// Overwrite old string in string table
-	strcpy((char *) oldname, supername);
-    }
-    else {
-	long strx;
-
-	// Make sure we have a string table as well for this symbol
-	if (!file->fNewStrings) {
-	    file->fNewStrings = DataCreate(0);
-	    return_if(!file->fNewStrings, NULL,
-		("Unable to allocate string table for %s\n", file->fPath));
-	}
-
-	// Find the end of the fNewStrings data structure;
-	strx = DataGetLength(file->fNewStrings);
-	return_if(!DataAppendBytes(file->fNewStrings, supername, namelen + 1),
-	    NULL, ("Unable to grow string table for %s\n", file->fPath));
-
-	// now add the current table size to the offset
-	sym->n_un.n_strx = strx + file->fSymtab->strsize;
-    }
-
-    // Mark the symbol as having been processed by negating it.
-    // Also note that we have dirtied the file and need to repair the
-    // symbol table.
-    sym->n_un.n_strx = -sym->n_un.n_strx;
-    file->fSymbolsDirty = true; 
-    return sym;
-}
-
-static enum patchState
-symbolCompare(const struct fileRecord *file,
-	      const struct nlist *classsym,
-	      const char *supername)
-{
-    const char *classname;
-    
-
-    // Check to see if the target function is locally defined
-    // if it is then we can assume this is a local vtable override
-    if ((classsym->n_type & N_TYPE) != N_UNDF)
-	return kSymbolLocal;
-
-    // Check to see if both symbols point to the same symbol name
-    // if so then we are still identical.
-    classname = symbolname(file, classsym);
-    if (!strcmp(classname, supername))
-	return kSymbolIdentical;
-
-    // Right now we know that the target's vtable entry is different from the
-    // superclass' vtable entry.  This means that we will have to apply a
-    // patch to the current entry, however before returning lets check to
-    // see if we have a _RESERVEDnnn field 'cause we can use this as a
-    // registration point that must align between vtables.
-    if (!strncmp(supername, kReservedPrefix, sizeof(kReservedPrefix) - 1))
-	return kSymbolMismatch;
-
-    // OK, we have a superclass difference where the superclass doesn't
-    // reference a pad function so assume that the superclass is correct.
-    if (!strncmp(classname, kReservedPrefix, sizeof(kReservedPrefix) - 1))
-	return kSymbolPadUpdate; 
-    else
-	return kSymbolSuperUpdate;
-}
-
-static Boolean patchVTable(struct metaClassRecord *metaClass)
-{
-    struct metaClassRecord *super = NULL;
-    struct fileRecord *file;
-    struct patchRecord *patchedVTable;
-    struct relocRecord **curReloc, **vtableRelocs, **endSection;
-    unsigned char *sectionBase;
-    int classSize;
-
-    // Should never occur but it doesn't cost us anything to check.
-    if (metaClass->fPatchedVTable)
-	return true;
-
-    // Do we have a valid vtable to patch?
-    return_if(!metaClass->fVTableSym,
-	false, ("Internal error - no class vtable symbol?\n"));
-
-    file = metaClass->fFile;
-
-    // If the metaClass we are being to ask is in the kernel then we
-    // need to do a quick scan to grab the fPatchList in a reliable format
-    // however we don't need to check the superclass in the kernel
-    // as the kernel vtables are always correct wrt themselves.
-    // Note this ends the superclass chain recursion.
-    return_if(file->fIsKernel,
-	false, ("Internal error - patchVTable shouldn't used for kernel\n"));
-
-    if (!metaClass->fSuperName)
-	return false;
-
-    // The class isn't in the kernel so make sure that the super class 
-    // is patched before patching ouselves.
-    super = getClass(sMergeMetaClasses, metaClass->fSuperName);
-    return_if(!super, false, ("Can't find superclass for %s : %s \n",
-	metaClass->fClassName, metaClass->fSuperName));
-
-    // Superclass recursion if necessary
-    if (!super->fPatchedVTable) {
-	Boolean res;
-
-	if (super->fFile->fIsKernel)
-	    res = resolveKernelVTable(super);
-	else
-	    res = patchVTable(super);
-	if (!res)
-	    return false;
-    }
-
-DEBUG_LOG(("Patching %s\n", metaClass->fClassName));	// @@@ gvdl:
-
-    // We are going to need the base and the end
-
-    sectionBase = getSectionForSymbol(file,
-	metaClass->fVTableSym, (void ***) &endSection);
-    if (-1 == (long) sectionBase)
-	return false;
-
-    vtableRelocs  = (struct relocRecord **)
-			(sectionBase + metaClass->fVTableSym->n_value);
-    curReloc = vtableRelocs + kVTablePreambleLen;
-    for (classSize = 0; curReloc < endSection && *curReloc; classSize++)
-	curReloc++;
-
-    return_if(*curReloc, false,
-	("%s isn't a valid kext, short section\n", file->fPath));
-
-    patchedVTable = (struct patchRecord *)
-	malloc((classSize + 1) * sizeof(struct patchRecord));
-    return_if(!patchedVTable, false, ("patchedVTable - no memory\n"));
-
-    do {
-	struct patchRecord *curPatch;
-	struct nlist *symbol;
-
-	curPatch = patchedVTable;
-	curReloc = vtableRelocs + kVTablePreambleLen;
-
-	// Grab the super table patches if necessary
-	// Can't be patching a kernel table as we don't walk super
-	// class chains in the kernel symbol space.
-	if (super && super->fPatchedVTable) {
-	    const struct patchRecord *spp;
-
-	    spp = super->fPatchedVTable;
-
-	    for ( ; spp->fSymbol; curReloc++, spp++, curPatch++) {
-		const char *supername =
-		    symbolname(super->fFile, spp->fSymbol);
-
-                symbol = (struct nlist *) (*curReloc)->fSymbol;
-
-		curPatch->fType = symbolCompare(file, symbol, supername);
-		switch (curPatch->fType) {
-		case kSymbolIdentical:
-		case kSymbolLocal:
-		    break;
-    
-		case kSymbolSuperUpdate:
-		    symbol = getNewSymbol(file, (*curReloc), supername);
-		    break;
-
-		case kSymbolPadUpdate:
-		    symbol = fixOldSymbol(file, (*curReloc), supername);
-		    break;
-
-		case kSymbolMismatch:
-		    errprintf("%s is not compatible with its %s superclass, "
-			      "broken superclass?\n",
-			      metaClass->fClassName, super->fClassName);
-		    goto abortPatch;
-
-		default:
-		    errprintf("Internal error - unknown patch type\n");
-		    goto abortPatch;
-		}
-		if (symbol) {
-		    curPatch->fSymbol = symbol;
-		    (*curReloc)->fSymbol = symbol;
-		}
-		else
-		    goto abortPatch;
-	    }
-	}
-
-	// Copy the remainder of this class' vtable into the patch table
-	for (; *curReloc; curReloc++, curPatch++) {
-	    // Local reloc symbols
-	    curPatch->fType = kSymbolLocal;
-	    curPatch->fSymbol = (struct nlist *) (*curReloc)->fSymbol;
-	}
-
-	// Tag the end of the patch vtable
-	curPatch->fSymbol = NULL;
-
-	metaClass->fPatchedVTable = patchedVTable;
-	return true;
-    } while(0);
-
-abortPatch:
-    if (patchedVTable)
-	free(patchedVTable);
-
-    return false;
-}
-
-static Boolean growImage(struct fileRecord *file, vm_size_t delta)
-{
-#if !KERNEL
-    file->fMachOSize += delta;
-    return (file->fMachO + file->fMachOSize <= file->fPadEnd);
-#else /* KERNEL */
-    vm_address_t startMachO, endMachO, endMap;
-    vm_offset_t newMachO;
-    vm_size_t newsize;
-    unsigned long i, nsect, nclass = 0;
-    struct metaClassRecord **classes = NULL;
-    struct sectionRecord *section;
-    kern_return_t ret;
-
-    startMachO = (vm_address_t) file->fMachO;
-    endMachO = startMachO + file->fMachOSize + delta;
-    endMap   = (vm_address_t) file->fMap + file->fMapSize;
-
-    // Do we have room in the current mapped image
-    if (endMachO < round_page(endMap)) {
-	file->fMachOSize += delta;
-	return true;
-    }
-
-    newsize = endMachO - startMachO;
-    if (newsize < round_page(file->fMapSize)) {
-	// We have room in the map if we shift the macho image within the
-	// current map.  We will have to patch up pointers into the object.
-	newMachO = (vm_offset_t) file->fMap;
-	bcopy((char *) startMachO, (char *) newMachO, file->fMachOSize);
-    }
-    else if (file->fIsKmem) {
-	// kmem_alloced mapping so we can try a kmem_realloc
-	ret = kmem_realloc(kernel_map,
-			  (vm_address_t) file->fMap,
-			  (vm_size_t) file->fMapSize,
-			  &newMachO,
-			  newsize);
-	if (KERN_SUCCESS != ret)
-	    return false;
-
-	// If the mapping didn't move then just return
-	if ((vm_address_t) file->fMap == newMachO) {
-	    file->fMachOSize = file->fMapSize = newsize;
-	    return true;
-	}
-
-	// We have relocated the kmem image so we are going to have to
-	// move all of the pointers into the image around.
-    }
-    else {
-	// The image doesn't have room for us and I can't kmem_realloc
-	// then I just have to bite the bullet and copy the object code
-	// into a bigger memory segment
-	ret = kmem_alloc(kernel_map, &newMachO, newsize);
-	
-	if (KERN_SUCCESS != ret)
-	    return false;
-	bcopy((char *) startMachO, (void *) newMachO, file->fMachOSize);
-	file->fIsKmem = true;
-    }
-
-
-    file->fMap = file->fMachO = (unsigned char *) newMachO;
-    file->fMapSize = newsize;
-    file->fMachOSize += delta; // Increment the image size
-
-    // If we are here then we have shifted the object image in memory
-    // I really should change all of my pointers into the image to machO offsets
-    // but I have run out of time.  So I'm going to very quickly go over the
-    // cached data structures and add adjustments to the addresses that are
-    // affected.  I wonder how long it will take me to get them all.
-    //
-    // For every pointer into the MachO I need to add an adjustment satisfying
-    // the following simultanous equations
-    // addr_old = macho_old + fixed_offset
-    // addr_new = macho_new + fixed_offset	therefore:
-    // addr_new = addr_old + (macho_new - macho_old)
-#define REBASE(addr, delta)	( ((vm_address_t) (addr)) += (delta) )
-    delta = newMachO - startMachO;
-
-    // Rebase the cached in object 'struct symtab_command' pointer
-    REBASE(file->fSymtab, delta);
-
-    // Rebase the cached in object 'struct nlist' pointer for all symbols
-    REBASE(file->fSymbolBase, delta);
-
-    // Rebase the cached in object 'struct nlist' pointer for local symbols
-    REBASE(file->fLocalSyms, delta);
-
-    // Rebase the cached in object 'char' pointer for the string table
-    REBASE(file->fStringBase, delta);
-
-    // Ok now we have to go over all of the relocs one last time
-    // to clean up the pad updates which had their string index negated
-    // to indicate that we have finished with them.
-    section = file->fSections;
-    for (i = 0, nsect = file->fNSects; i < nsect; i++, section++)
-	REBASE(section->fSection, delta);
-
-    // We only ever grow images that contain class lists so dont bother
-    // the check if file->fClassList is non-zero 'cause it can't be
-    // assert(file->fClassList);
-    nclass = DataGetLength(file->fClassList)
-	   / sizeof(struct metaClassRecord *);
-    classes = (struct metaClassRecord **) DataGetPtr(file->fClassList);
-    for (i = 0; i < nclass; i++) {
-	struct patchRecord *patch;
-
-	for (patch = classes[i]->fPatchedVTable; patch->fSymbol; patch++) {
-	    vm_address_t symAddr = (vm_address_t) patch->fSymbol;
-	    if (symAddr >= startMachO && symAddr < endMachO)
-		REBASE(patch->fSymbol, delta);
-	}
-    }
-
-
-#undef REBASE
-
-    return true;
-
-#endif /* KERNEL */
-}
-
-static Boolean
-prepareFileForLink(struct fileRecord *file)
-{
-    unsigned long i, last, numnewsyms, newsymsize, newstrsize;
-    struct sectionRecord *section;
-    struct nlist **symp, *sym;
-
-    // If we didn't even do a pseudo 'relocate' and dirty the image
-    // then we can just return now.
-    if (!file->fImageDirty)
-	return true;
-
-DEBUG_LOG(("Linking 2 %s\n", file->fPath));	// @@@ gvdl:
-
-    // We have to go over all of the relocs to repair the damage
-    // that we have done to the image when we did our 'relocation'
-    section = file->fSections;
-    for (i = 0, last = file->fNSects; i < last; i++, section++) {
-	unsigned char *sectionBase;
-	struct relocRecord *rec;
-	unsigned long j, nreloc;
-
-	if (section->fRelocCache) {
-	    sectionBase = file->fMachO + section->fSection->offset;
-	    nreloc = section->fSection->nreloc;
-	    rec = (struct relocRecord *) DataGetPtr(section->fRelocCache);
-    
-	    // We will need to repair the reloc list 
-	    for (j = 0; j < nreloc; j++, rec++) {
-		void **entry;
-		struct nlist *sym;
-    
-		// Repair Damage to object image
-		entry = (void **) (sectionBase + rec->fRInfo->r_address);
-		*entry = rec->fValue;
-
-		// Check if the symbol that this relocation entry points
-		// to is marked as erasable 
-		sym = (struct nlist *) rec->fSymbol;
-		if (sym && sym->n_type == (N_EXT | N_UNDF)
-		&&  sym->n_sect == (unsigned char) -1) {
-		    // clear mark now
-		    sym->n_un.n_strx = -sym->n_un.n_strx;
-		    sym->n_sect = NO_SECT;
-		}
-	    }
-
-	    // Clean up the fRelocCache we don't need it any more.
-	    DataRelease(section->fRelocCache);
-	    section->fRelocCache = 0;
-	}
-    }
-    file->fImageDirty = false;	// Image is clean
-
-    // If we didn't dirty the symbol table then just return
-    if (!file->fSymbolsDirty)
-	return true;
-
-    // calculate total file size increase and check against padding
-    numnewsyms  = (file->fNewSymbols)? DataGetLength(file->fNewSymbols) : 0;
-    numnewsyms /= sizeof(struct nlist *);
-    newsymsize  = numnewsyms * sizeof(struct nlist);
-    newstrsize  = (file->fNewStrings)? DataGetLength(file->fNewStrings) : 0;
-    newstrsize  = (newstrsize + 3) & ~3;	// Round to nearest word
-    
-    return_if(!growImage(file, newsymsize + newstrsize),
-	false, ("Unable to patch the extension, no memory\n", file->fPath));
-
-    // Push out the new symbol table if necessary
-    if (numnewsyms) {
-	caddr_t base;
-
-	// Move the string table out of the way of the grown symbol table
-	// Don't forget the '\0' from end of string table.
-	base = (caddr_t) file->fStringBase;
-	bcopy(base, base + newsymsize, file->fSymtab->strsize);
-	file->fStringBase     += newsymsize;
-	file->fSymtab->stroff += newsymsize;
-
-	// Now append the new symbols to the symbol table.
-	base = (caddr_t) file->fSymbolBase
-	     + file->fSymtab->nsyms * sizeof(struct nlist);
-	symp = (struct nlist **) DataGetPtr(file->fNewSymbols);
-	for (i = 0; i < numnewsyms; i++, base += sizeof(struct nlist), symp++)
-	    bcopy(*symp, base, sizeof(struct nlist));
-	file->fSymtab->nsyms  += numnewsyms;
-
-	DataRelease(file->fNewSymbols);
-	file->fNewSymbols = 0;
-    }
-
-    // Push out the new string table if necessary
-    if (newstrsize) {
-	caddr_t base = (caddr_t) file->fStringBase + file->fSymtab->strsize;
-	unsigned long actuallen = DataGetLength(file->fNewStrings);
-
-	// Set the last word in string table to zero before copying data
-	*((unsigned long *) ((char *) base + newstrsize - 4)) = 0;
-
-	// Now append the new strings to the end of the file
-	bcopy((caddr_t) DataGetPtr(file->fNewStrings), base, actuallen);
-
-	file->fSymtab->strsize += newstrsize;
-
-	DataRelease(file->fNewStrings);
-	file->fNewStrings = 0;
-    }
-
-    // Repair the symbol table string index values
-    // I used negative strx's to indicate symbol has been processed
-    sym = file->fSymbolBase;
-    for (i = 0, last = file->fSymtab->nsyms; i < last; i++, sym++) {
-	if (sym->n_un.n_strx < 0) {
-	    if ( sym->n_type != (N_EXT | N_UNDF)
-	    || (unsigned char) -1 != sym->n_sect)
-		sym->n_un.n_strx = -sym->n_un.n_strx;
-	    else {
-		// This symbol isn't being used by any vtable's reloc so
-		// convert it into an N_ABS style of symbol, remove the
-		// external bit and null out the symbol name.
-		bzero(sym, sizeof(*sym));
-		sym->n_type = N_ABS;	/* type flag, see below */
-	    }
-	}
-    }
-    file->fSymbolsDirty = false;
-
-    return true;
-}
-
-Boolean
-#if KERNEL
-kld_file_map(const char *pathName,
-	     unsigned char *map,
-	     size_t mapSize,
-	     Boolean isKmem)
-#else
-kld_file_map(const char *pathName)
-#endif /* KERNEL */
-{
-    struct fileRecord file, *fp = 0;
-
-    // Already done no need to repeat
-    fp = getFile(pathName);
-    if (fp)
-	return true;
-
-    bzero(&file, sizeof(file));
-    file.fPath = pathName;
-
-#if KERNEL
-    file.fMap = map;
-    file.fMapSize = mapSize;
-    file.fIsKmem = isKmem;
-#else
-    if (!mapObjectFile(&file))
-	return false;
-#endif /* KERNEL */
-
-    do {
-	const struct machOMapping {
-	    struct mach_header h;
-	    struct load_command c[1];
-	} *machO;
-	const struct load_command *cmd;
-	const struct nlist *sym;
-	unsigned int i, firstlocal, nsyms;
-	unsigned long strsize;
-	const char *strbase;
-	Boolean foundOSObject;
-
-	if (!findBestArch(&file))
-	    break;
-    
-	machO = (const struct machOMapping *) file.fMachO;
-	if (file.fMachOSize < machO->h.sizeofcmds)
-	    break;
-
-	// If the file type is MH_EXECUTE then this must be a kernel
-	// as all Kernel extensions must be of type MH_OBJECT
-	for (i = 0, cmd = &machO->c[0]; i < machO->h.ncmds; i++) {
-	    if (cmd->cmd == LC_SEGMENT) {
-		return_if(!parseSegments(&file, (struct segment_command *) cmd),
-		    false, ("%s isn't a valid mach-o, bad segment\n",
-			    file.fPath));
-	    }
-	    else if (cmd->cmd == LC_SYMTAB)
-		file.fSymtab = (struct symtab_command *) cmd;
-    
-	    cmd = (struct load_command *) ((UInt8 *) cmd + cmd->cmdsize);
-	}
-	break_if(!file.fSymtab,
-	    ("%s isn't a valid mach-o, no symbols\n", file.fPath));
-
-	// we found a link edit segment so recompute the bases
-	if (file.fSymbolBase) {
-	    struct segment_command *link =
-		(struct segment_command *) file.fSymbolBase;
-
-	    file.fSymbolBase = (struct nlist *)
-		(link->vmaddr + (file.fSymtab->symoff - link->fileoff));
-	    file.fStringBase = (char *)
-		(link->vmaddr + (file.fSymtab->stroff - link->fileoff));
-	    break_if( ( (caddr_t) file.fStringBase + file.fSymtab->strsize
-		      > (caddr_t) link->vmaddr + link->vmsize ),
-		("%s isn't a valid mach-o le, bad symbols\n", file.fPath));
-	}
-	else {
-	    file.fSymbolBase = (struct nlist *)
-		(file.fMachO + file.fSymtab->symoff); 
-	    file.fStringBase = (char *)
-		(file.fMachO + file.fSymtab->stroff); 
-	    break_if( ( file.fSymtab->stroff + file.fSymtab->strsize
-		      > file.fMachOSize ),
-		("%s isn't a valid mach-o, bad symbols\n", file.fPath));
-	}
-
-	// If this file the kernel and do we have an executable image
-	file.fIsKernel = (MH_EXECUTE == machO->h.filetype);
-	file.fNoKernelExecutable = (vm_page_size == file.fSymtab->symoff)
-				&& (file.fSections[0].fSection->size == 0);
-
-	// Search for the first non-stab symbol in table
-	strsize = file.fSymtab->strsize;
-	strbase = file.fStringBase;
-	sym = file.fSymbolBase;
-	firstlocal = 0;
-	foundOSObject = false;
-	for (i = 0, nsyms = file.fSymtab->nsyms; i < nsyms; i++, sym++) {
-	    if ((unsigned long) sym->n_un.n_strx > strsize)
-		break;
-
-	    // Find the first exported symbol
-	    if ( !file.fLocalSyms && (sym->n_type & N_EXT) ) {
-		file.fLocalSyms = sym;
-		firstlocal = i;
-	    }
-
-	    // Find the a OSObject based subclass by searching for symbols
-	    // that have a suffix of '.superClass'
-	    if (!foundOSObject
-	    && ((sym->n_type & (N_TYPE | N_EXT)) == (N_SECT | N_EXT)
-	     || (sym->n_type & (N_TYPE | N_EXT)) == (N_ABS | N_EXT))
-	    &&  sym->n_un.n_strx) {
-		const char *dot;
-
-		// Only search from the last '.' in the symbol.
-		// but skip the leading '_' in all symbols first.
-		dot = strrchr(strbase + sym->n_un.n_strx + 1, '.');
-		if (dot && !strcmp(dot, kSuperClassSuffix))
-		    foundOSObject = true;
-	    }
-
-	    // Find the last local symbol
-	    if ( !file.fNLocal && sym->n_type == (N_EXT | N_UNDF) )
-		file.fNLocal = i - firstlocal;
-
-	}
-	break_if(i < nsyms,
-	    ("%s isn't a valid mach-o, bad symbol strings\n", file.fPath));
-
-	break_if(!file.fLocalSyms, ("%s has no symbols?\n", file.fPath));
-
-	// If we don't have any undefined symbols then all symbols
-	// must be local so just compute it now if necessary.
-	if ( !file.fNLocal )
-	    file.fNLocal = i - firstlocal;
-
-	fp = addFile(&file);
-	if (!fp)
-	    break;
-
-	if (foundOSObject && !getMetaClassGraph(fp))
-	    break;
-
-	if (file.fIsKernel)
-	    sKernelFile = fp;
-#if KERNEL
-	if (!sKernelFile) {
-	    extern struct mach_header _mh_execute_header;
-	    extern struct segment_command *getsegbyname(char *seg_name);
-    
-	    struct segment_command *sg;
-	    size_t kernelSize;
-	    Boolean ret;
-
-	    sg = (struct segment_command *) getsegbyname(kLinkEditSegName); 
-	    break_if(!sg, ("Can't find kernel link edit segment\n"));
-    
-	    kernelSize = sg->vmaddr + sg->vmsize - (size_t) &_mh_execute_header;
-	    ret = kld_file_map(kld_basefile_name,
-	        (unsigned char *) &_mh_execute_header, kernelSize,
-		/* isKmem */ false);
-	    break_if(!ret, ("kld can't map kernel file"));
-	}
-#endif	/* KERNEL */
-
-	return true;
-    } while(0);
-
-    removeFile(&file);
-
-    return false;
-}
-
-void *kld_file_getaddr(const char *pathName, long *size)
-{
-    struct fileRecord *file = getFile(pathName);
-
-    if (!file)
-	return 0;
-
-    if (size)
-	*size = file->fMachOSize;
-
-    return file->fMachO;
-}
-
-void *kld_file_lookupsymbol(const char *pathName, const char *symname)
-{
-    struct fileRecord *file = getFile(pathName);
-    const struct nlist *sym;
-    const struct section *section;
-    unsigned char *sectionBase;
-    unsigned char sectind;
-
-    return_if(!file,
-	NULL, ("Unknown file %s\n", pathName));
-
-    sym = findSymbolByName(file, symname);
-
-    // May be a non-extern symbol so look for it there
-    if (!sym) {
-	const char *strbase;
-	unsigned int i, nsyms;
-
-	sym = file->fSymbolBase;
-	strbase = file->fStringBase;
-	for (i = 0, nsyms = file->fSymtab->nsyms; i < nsyms; i++, sym++) {
-	    if ( (sym->n_type & N_EXT) ) {
-		sym = 0;
-		break;	// Terminate search when we hit an extern
-	    }
-	    if ( (sym->n_type & N_STAB) )
-		continue;
-	    if ( !strcmp(symname, strbase + sym->n_un.n_strx) )
-		break;
-	}
-    }
-
-    return_if(!sym,
-	NULL, ("Unknown symbol %s in %s\n", symname, pathName));
-
-    // Is the vtable in a valid section?
-    sectind = sym->n_sect;
-    return_if(sectind == NO_SECT || sectind > file->fNSects, NULL,
-	("Malformed object file, invalid section reference for %s in %s\n",
-	    symname, pathName));
-
-    section = file->fSections[sectind - 1].fSection;
-    sectionBase = file->fMachO + section->offset - section->addr;
-
-    return (void *) (sectionBase + sym->n_value);
-}
-
-Boolean kld_file_merge_OSObjects(const char *pathName)
-{
-    struct fileRecord *file = getFile(pathName);
-
-    return_if(!file,
-	false, ("Internal error - unable to find file %s\n", pathName));
-
-    return mergeOSObjectsForFile(file);
-}
-
-Boolean kld_file_patch_OSObjects(const char *pathName)
-{
-    struct fileRecord *file = getFile(pathName);
-    struct metaClassRecord **classes;
-    unsigned long i, last;
-
-    return_if(!file,
-	false, ("Internal error - unable to find file %s\n", pathName));
-
-DEBUG_LOG(("Patch file %s\n", pathName));	// @@@ gvdl:
-
-    // If we don't have any classes we can return now.
-    if (!file->fClassList)
-	return true;
-
-    // If we haven't alread merged the kernel then do it now
-    if (!sMergedKernel && sKernelFile)
-	mergeOSObjectsForFile(sKernelFile);
-    return_if(!sMergedKernel, false, ("Internal error no kernel?\n"));
-
-    if (!mergeOSObjectsForFile(file))
-	return false;
-
-    // Patch all of the classes in this executable
-    last = DataGetLength(file->fClassList) / sizeof(void *);
-    classes = (struct metaClassRecord **) DataGetPtr(file->fClassList);
-    for (i = 0; i < last; i++) {
-	if (!patchVTable(classes[i]))
-	    return false;
-    }
-
-    return true;
-}
-
-Boolean kld_file_prepare_for_link()
-{
-    if (sMergedFiles) {
-	unsigned long i, nmerged = 0;
-	struct fileRecord **files;
-    
-	// Check to see if we have already merged this file
-	nmerged = DataGetLength(sMergedFiles) / sizeof(struct fileRecord *);
-	files = (struct fileRecord **) DataGetPtr(sMergedFiles);
-	for (i = 0; i < nmerged; i++) {
-	    if (!prepareFileForLink(files[i]))
-		return false;
-	}
-    }
-
-    // Clear down the meta class table and merged file lists
-    DataRelease(sMergeMetaClasses);
-    DataRelease(sMergedFiles);
-    sMergedFiles = sMergeMetaClasses = NULL;
-    sMergedKernel = false;
-
-    return true;
-}
-
-void kld_file_cleanup_all_resources()
-{
-    unsigned long i, nfiles;
-
-#if KERNEL	// @@@ gvdl:
-    // Debugger("kld_file_cleanup_all_resources");
-#endif
-
-    if (!sFilesTable || !(nfiles = DataGetLength(sFilesTable)))
-	return;	// Nothing to do just return now
-
-    nfiles /= sizeof(struct fileRecord *);
-    for (i = 0; i < nfiles; i++)
-	removeFile(((void **) DataGetPtr(sFilesTable))[i]);
-
-    // Don't really have to clean up anything more as the whole
-    // malloc engine is going to be released and I couldn't be bothered.
-}
-
-#if !KERNEL
-Boolean kld_file_debug_dump(const char *pathName, const char *outName)
-{
-    const struct fileRecord *file = getFile(pathName);
-    int fd;
-    Boolean ret = false;
-
-    return_if(!file, false, ("Unknown file %s for dumping\n", pathName));
-
-    fd = open(outName, O_WRONLY|O_CREAT|O_TRUNC, 0666);
-    return_if(-1 == fd, false, ("Can't create output file %s - %s(%d)\n",
-	outName, strerror(errno), errno));
-
-    do {
-	break_if(-1 == write(fd, file->fMachO, file->fMachOSize),
-	    ("Can't dump output file %s - %s(%d)\n", 
-		outName, strerror(errno), errno));
-	ret = true;
-    } while(0);
-
-    close(fd);
-
-    return ret;
-}
-#endif /* !KERNEL */
-
diff --git a/kmodload.tproj/kld_patch.h b/kmodload.tproj/kld_patch.h
deleted file mode 100644
index b0e6058..0000000
--- a/kmodload.tproj/kld_patch.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * History:
- *  2001-05-30 	gvdl	Initial implementation of the vtable patcher.
- */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-#if KERNEL
-extern Boolean kld_file_map(const char *pathName,
-			    unsigned char *map, size_t mapSize,
-			    Boolean isKmem);
-#else
-extern Boolean kld_file_map(const char *pathName);
-
-extern void *
-    kld_file_lookupsymbol(const char *pathName, const char *symbolname);
-
-Boolean kld_file_debug_dump(const char *pathName, const char *outName);
-#endif /* KERNEL */
-
-extern void *kld_file_getaddr(const char *pathName, long *size);
-
-extern Boolean kld_file_merge_OSObjects(const char *pathName);
-
-extern Boolean kld_file_patch_OSObjects(const char *pathName);
-
-extern Boolean kld_file_prepare_for_link();
-
-extern void kld_file_cleanup_all_resources();
-
-__END_DECLS
diff --git a/kmodload.tproj/kmodload.8 b/kmodload.tproj/kmodload.8
deleted file mode 100644
index a5e6914..0000000
--- a/kmodload.tproj/kmodload.8
+++ /dev/null
@@ -1,93 +0,0 @@
-.\"
-.\" Copyright (c) 1997 Doug Rabson
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\"	$Id: kmodload.8,v 1.3 2000/12/15 05:33:01 lindak Exp $
-.\"
-.Dd April 8, 1999
-.Dt KMODLOAD 8
-.Os FreeBSD
-.Sh NAME
-.Nm kmodload
-.Nd loads and starts a kernel module
-.Sh SYNOPSIS
-.Nm kmodload
-.Op Fl v
-.Op Fl k Ar kernelfile
-.Op Fl d Ar dependencyfile
-.Op Fl o Ar symbolfile
-.Ar modulefile
-.Sh DESCRIPTION
-The
-.Nm
-loads the file 
-.Ar modulefile
-into the kernel and starts its execution.
-.Pp
-The following options are available:
-.Bl -tag -width indent
-.It Fl v
-Be more verbose.
-.It Fl k Ar kernelfile
-Use alternate file
-.Ar kernelfile
-instead of default file /mach for linking
-.Ar modulefile .
-.It Fl d Ar dependencyfile
-Add symbols from
-.Ar dependencyfile
-to kernel symbols prior to linking of
-.Ar modulefile .
-The file 
-.Ar dependencyfile
-must already be loaded.
-.It Fl o Ar symbolfile
-Creates file named
-.Ar symbolfile
-that contains statically linked output suitable to use with
-.Xr gdb 1 
-for remote debugging.
-.El
-.Sh FILES
-.Bl -tag -width /modules -compact
-.It Pa /System/Library/Extensions
-directory containing loadable kernel modules.
-.Sh DIAGNOSTICS
-The
-.Nm
-utility exits with a status of 0 on success.
-A status of 1 indicates a usage error.
-A status of 2 indicates a indicates a permissions error.
-A status of 3 indicates a problem with linking the module.
-A status of 4 indicates a internal or system error.
-A status of 5 indicates the module has already been loaded. 
-.Sh SEE ALSO
-.Xr kmodstat 8 ,
-.Xr kmodsyms 8 ,
-.Xr kmodunload 8
-.Sh HISTORY
-The
-.Nm
-command is based on the command kldload written by
-.An Doug Rabson Aq dfr@FreeBSD.org
diff --git a/kmodload.tproj/kmodload.c b/kmodload.tproj/kmodload.c
deleted file mode 100644
index 4108282..0000000
--- a/kmodload.tproj/kmodload.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1997 Doug Rabson
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Original code from:
- *	"kldload.c,v 1.5 1998/07/06 06:58:32 charnier Exp"
- */
-#ifndef lint
-static const char rcsid[] =
-	"$Id: kmodload.c,v 1.10 2001/08/02 20:57:01 lindak Exp $";
-#endif /* not lint */
-
-#include <stdlib.h>
-#include <err.h>
-#include <sys/file.h>
-#include <nlist.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <paths.h>
-
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <mach/mach_host.h>
-#include <mach-o/kld.h>
-#include <mach-o/fat.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include "kld_patch.h"
-
-#define KMOD_ERROR_USAGE	1
-#define KMOD_ERROR_PERMS	2
-#define KMOD_ERROR_LOADING	3		
-#define KMOD_ERROR_INTERNAL	4
-#define KMOD_ERROR_ALREADY	5
-
-#define kKMOD_INFO_SYMBOLNAME "_kmod_info"
-#define kKmodsymsName "kmodsyms"
-
-static mach_port_t kernel_port;
-static mach_port_t kernel_priv_port;
-
-static kmod_info_t *module_dependencies = 0;
-static vm_address_t kernel_alloc_address = 0;
-static unsigned long kernel_alloc_size = 0;
-static vm_address_t kernel_load_address = 0;
-static unsigned long kernel_load_size = 0;
-static unsigned long kernel_hdr_size = 0;
-static unsigned long kernel_hdr_pad = 0;
-static unsigned long faked_kernel_load_address = 0;
-
-static kmod_info_t *loaded_modules = 0;
-static int loaded_count = 0;
-
-static char *progname = "program name?";
-static int kmodsyms = 0;
-static int link_addrs_set = 0;
-static int verbose = 0;
-
-static char *debugdumpfile = NULL;
-
-// must not be static; kld library calls
-extern void			kld_error_vprintf(const char *format, va_list ap);
-static void			e_printf(const char *fmt, ...);
-static void			v_printf(const char *fmt, ...);
-
-static void			machwarn(int error, const char *message);
-static void			macherr(int error, const char *message);
-
-static unsigned long	linkedit_address(unsigned long size,
-						 unsigned long headers_size);
-static void			abort_load(int exitcode, const char *fmt, ...);
-static void			map_and_patch(const char *base,
-								  const char **library_paths,
-								  const char *module);
-static void			link_base(const char *base,
-					  const char **dependency_paths,
-					  const vm_address_t *dependency_addrs);
-static void			clear_globals(void);
-static kmod_info_t *map_module(const char *filename);
-static struct mach_header *link_module(const char *filename, 
-					     const char *output);
-static vm_address_t		update_kmod_info(struct mach_header *mach_header);
-static kmod_t			load_module(struct mach_header *mach_header,
-					    vm_address_t info);
-static void 			set_module_dependencies(kmod_t id);
-static void			start_module(kmod_t id);
-
-static void
-usage(void)
-{
-	if (kmodsyms) {
-		fprintf(stderr, "usage: %s [-v] [-k kernelfile] [-d dependencyfile] -o symbolfile modulefile\n", progname);
-		fprintf(stderr, "       %s [-v]  -k kernelfile  [-d dependencyfile@address] -o symbolfile modulefile@address\n",
-			progname);
-	} else {
-		fprintf(stderr, "usage: %s [-v] [-k kernelfile] [-d dependencyfile] [-o symbolfile] modulefile\n", progname);
-	}
-	fflush(stderr);
-	exit(KMOD_ERROR_USAGE);
-}
-
-int
-main(int argc, char** argv)
-{
-	int c, r, i;
-	char * kernel = _PATH_UNIX;
-	int kernel_set = 0;
-	char * gdbfile = 0;
-#define MAX_DEPENDANCIES	128
-	char * dependencies[MAX_DEPENDANCIES];
-	vm_address_t loaded_addresses[MAX_DEPENDANCIES];
-	int dependency_count = 0;
-	struct mach_header *rld_header;
-
-	char * module_path = "";
-	vm_address_t module_info = 0;
-	vm_address_t module_faked_address = 0;
-	kmod_t module_id = 0;
-	kmod_info_t *file_kinfo;
-
-	if ((progname = strrchr(argv[0], '/')) == NULL)
-		progname = argv[0];
-	else
-		++progname;
-
-	kmodsyms = !strcmp(progname, kKmodsymsName);
-
-	// XXX things to add:
-	//  -p data string to send as outofband data on start
-	//  -P data file to send as outofband data on start
-
-	while ((c = getopt(argc, argv, "D:d:o:k:v")) != -1)
-		switch (c) {
-		case 'd':
-			dependencies[dependency_count] = optarg;
-			if (kmodsyms) {
-				char *address;
-				if ((address = strrchr(optarg, '@'))) {
-					*address++ = 0;
-					loaded_addresses[dependency_count] = strtoul(address, NULL, 0);
-					link_addrs_set++;
-				} else {
-					loaded_addresses[dependency_count] = 0;
-				}
-			}
-			if (++dependency_count == MAX_DEPENDANCIES) {
-				abort_load(KMOD_ERROR_INTERNAL, 
-					"internal error, dependency count overflow."); 
-			}
-			break;
-		case 'o':
-			gdbfile = optarg;
-			break;
-		case 'k':
-			kernel_set++;
-			kernel = optarg;
-			break;
-		case 'v':
-			verbose = 1;
-			break;
-		case 'D':
-			debugdumpfile = optarg;
-			break;
-		default:
-			usage();
-		}
-	argc -= optind;
-	argv += optind;
-
-	dependencies[dependency_count] = 0;
-	loaded_addresses[dependency_count] = 0;
-
-	if (argc != 1) usage();
-
-	module_path = argv[0];
-
-	if (kmodsyms) {
-		char *address;
-
-		if (!gdbfile) usage();
-
-		// check for @address
-		if ((address = strrchr(module_path, '@'))) {
-			*address++ = 0;
-			module_faked_address = strtoul(address, NULL, 0);
-			link_addrs_set++;
-		} else {
-			module_faked_address = 0;
-		}
-
-		// if any arg uses @address then they all must be and the kernel must be set
-		if (link_addrs_set) {
-			if (!kernel_set) usage();
-			if (!module_faked_address) usage();
-			for (i=0; i < dependency_count; i++) {
-				if (!loaded_addresses[i]) usage();
-			}
-		}
-	}
-
-	// map the module if possible, map_module will fail if there is a problem
-	file_kinfo = map_module(module_path);
-
-	if (!link_addrs_set) {
-		kmod_info_t *k;
-
-		// we only need the kernel port if we need to lookup loaded kmods
-		r = task_for_pid(mach_task_self(), 0, &kernel_port);
-		machwarn(r, "unable to get kernel task port");
-		if (KERN_SUCCESS != r) {
-			abort_load(KMOD_ERROR_PERMS,
-				"You must be running as root to load modules in the kernel.");
-		}
-
-		//get loaded modules
-		r = kmod_get_info(kernel_port, (void *)&loaded_modules, &loaded_count);  // never freed
-		macherr(r, "kmod_get_info() failed");
-
-		// check to see if the module has been loaded
-		k = loaded_modules;
-		while (k) {
-			if (!strcmp(k->name, file_kinfo->name)) {
-				if (!kmodsyms) {
-					abort_load(KMOD_ERROR_ALREADY,
-						"the module named '%s' is already loaded.", k->name); 
-				} else {
-					module_faked_address = k->address;
-				}
-				break;
-			}
-			k = (k->next) ? (k + 1) : 0;
-		}
-
-		if (kmodsyms && !module_faked_address) {
-			abort_load(KMOD_ERROR_USAGE,
-				"the module named '%s' has not been loaded.", file_kinfo->name);
-		}
-		
-		//XXX it would be nice to be able to verify this is the correct kernel
-		//XXX by comparing the kernel version strings (once we have them)
-	}
-
-	map_and_patch(kernel, dependencies, module_path);
-	if (debugdumpfile) kld_file_debug_dump(module_path, debugdumpfile);
-
-	// Tell the kld linker where to get its load address from
-	kld_address_func(linkedit_address);
-
-	// link the kernel along with any dependencies
-	link_base(kernel, dependencies, loaded_addresses);
-
-	if (kmodsyms) {
-	    faked_kernel_load_address = module_faked_address;
-
-	    if (!faked_kernel_load_address) {
-			abort_load(KMOD_ERROR_INTERNAL,
-			  "internal error, fell thru without setting module load address.");
-	    }
-	}
-
-	rld_header = link_module(module_path, gdbfile);
-	module_info = update_kmod_info(rld_header);
-
-	if (kmodsyms) return 0;
-
-	// we need the priv port to load modules into the kernel
-	kernel_priv_port = mach_host_self();  /* if we are privileged */
-
-	module_id = load_module(rld_header, module_info);
-	set_module_dependencies(module_id);
-	start_module(module_id);
-
-	return 0;
-}
-
-static void
-machwarn(int error, const char *message)
-{
-	if (KERN_SUCCESS != error)
-		e_printf("%s: %s", message, mach_error_string(error));
-}
-
-static void
-macherr(int error, const char *message)
-{
-	if (KERN_SUCCESS != error)
-		abort_load(KMOD_ERROR_INTERNAL,
-			"%s: %s", message, mach_error_string(error));
-}
-
-static kmod_info_t *map_module(const char *filename)
-{
-	kmod_info_t *file_kinfo;
-
-	if (!kld_file_map(filename))
-		exit(KMOD_ERROR_LOADING);
-
-	file_kinfo = kld_file_lookupsymbol(filename, kKMOD_INFO_SYMBOLNAME);
-	if (!file_kinfo) {
-		abort_load(KMOD_ERROR_USAGE,
-			"%s is not a valid kernel module.", filename);
-	}
-	
-	return file_kinfo;
-}
-
-static void
-map_and_patch(const char *base, const char **library_paths, const char *module)
-{
-	if (!kld_file_map(base))
-		exit(KMOD_ERROR_INTERNAL);
-	if (!kld_file_merge_OSObjects(base))
-		abort_load(KMOD_ERROR_LOADING, NULL);
-
-	if (*library_paths) {
-		char **library;
-		for (library = library_paths; *library; library++) {
-			map_module(*library);
-			if (!kld_file_patch_OSObjects(*library))
-				abort_load(KMOD_ERROR_LOADING, NULL);
-		}
-	}
-
-	// Patch the vtables of the object module we are about to load
-	// The module has already been mapped in the main() routine as part
-	// of validation
-	if (!kld_file_patch_OSObjects(module))
-		abort_load(KMOD_ERROR_LOADING, NULL);
-
-	// During the patch up process the mapped images were modified
-	// to avoid having to allocate more data than necessary.
-	// Now we have to give the patcher a chance to clean up after itself.
-	if (!kld_file_prepare_for_link())
-		abort_load(KMOD_ERROR_LOADING, NULL);
-}
-
-static void
-link_base(const char *base,
-	  const char **dependency_paths,
-	  const vm_address_t *dependency_addrs)
-{
-	struct mach_header *rld_header;
-	char *base_addr;
-	long base_size;
-	int ok;
-
-	// Get the address and size of the base, usually the kernel
-	base_addr = kld_file_getaddr(base, &base_size);
-	if (!base_addr)
-		exit(KMOD_ERROR_INTERNAL);	// Error reported by kld library.
-
-	ok = kld_load_basefile_from_memory(base, base_addr, base_size);
-	fflush(stdout);
-	if (!ok)
-		abort_load(KMOD_ERROR_LOADING, "kld_load_basefile(%s) failed.", base); 
-
-	if (*dependency_paths) {
-		char **dependency = dependency_paths;
-		const vm_address_t *load_addr = dependency_addrs;
-
-		while (*dependency) {
-			kmod_info_t *file_kinfo;
-
-			// Find the kmod_info structure in the image.
-			file_kinfo =
-				kld_file_lookupsymbol(*dependency, kKMOD_INFO_SYMBOLNAME);
-			if (!file_kinfo) {
-				abort_load(KMOD_ERROR_USAGE, 
-					"%s is not a valid kernel module.", *dependency);
-			}
-
-			// find the address that this dependency is loaded at
-			if (kmodsyms && *load_addr) {
-				faked_kernel_load_address = *load_addr;
-			} else {
-				kmod_info_t *k;
-				kmod_info_t *tmp;
-				int found_it = 0;
-
-				// match up file version of kmod_info with kernel version
-				k = loaded_modules;
-				while (k) {
-					if (!strcmp(k->name, file_kinfo->name)) {
-						if (strcmp(k->version, file_kinfo->version)) {
-							e_printf("loaded kernel module '%s' version differs.", *dependency);
-							abort_load(KMOD_ERROR_LOADING, 
-								"loaded version '%s', file version '%s'.",
-								k->version, file_kinfo->version);
-						}
-						found_it++;
-						break;
-					}
-					k = (k->next) ? (k + 1) : 0;
-				}
-				if (!found_it) {
-					abort_load(KMOD_ERROR_USAGE, 
-						"kernel module '%s' is not loaded.", *dependency);
-				}	
-			
-				tmp = malloc(sizeof(kmod_info_t));
-				if (!tmp)
-					abort_load(KMOD_ERROR_LOADING, "no memory.");
-
-				*tmp = *k;
-				tmp->next = module_dependencies;
-				module_dependencies = tmp;
-
-				faked_kernel_load_address = k->address;
-			}
-
-			rld_header = link_module(*dependency, 0);
-
-			(void) update_kmod_info(rld_header);
-
-			dependency++; load_addr++;
-		}
-		/* make sure we clear these so clean up does the right thing. */
-		clear_globals();
-	}
-}
-
-#if !defined(page_round)
-#define page_trunc(p) ((int)(p)&~(vm_page_size-1))
-#define page_round(p) page_trunc((int)(p)+vm_page_size-1)
-#endif
-
-static unsigned long
-linkedit_address(unsigned long size, unsigned long headers_size)
-{
-    int r;
-    unsigned long round_segments_size;
-    unsigned long round_headers_size;
-    unsigned long round_size;
-
-    kernel_load_size = size;  // The actual size allocated by kld_load...
-
-    round_headers_size = page_round(headers_size);
-    round_segments_size = page_round(size - headers_size);
-    round_size =  round_headers_size + round_segments_size;
-
-    kernel_alloc_size = round_size;
-    kernel_hdr_size = headers_size;  // will need to be rounded to page *after* link.
-    kernel_hdr_pad = round_headers_size - headers_size;
-
-    if (faked_kernel_load_address) {
-        kernel_load_address = faked_kernel_load_address + kernel_hdr_pad;
-        v_printf("Returning fake load address of 0x%8x", kernel_load_address);
-        return kernel_load_address;
-    }
-    if (kmodsyms) {
-		abort_load(KMOD_ERROR_INTERNAL, 
-			"internal error, almost tried to alloc kernel memory."); 
-    }
-
-    r = vm_allocate(kernel_port, &kernel_alloc_address, 
-        kernel_alloc_size, TRUE);
-    macherr(r, "unable to allocate kernel memory");
-
-    v_printf("allocated %ld bytes in kernel space at 0x%8x",
-        kernel_alloc_size, kernel_alloc_address);
-
-    kernel_load_address = kernel_alloc_address + kernel_hdr_pad;
-
-    v_printf("Returning load address of 0x%x", kernel_load_address);
-
-    return kernel_load_address;
-}
-
-static void
-clear_globals(void)
-{
-    faked_kernel_load_address = 0;
-    kernel_alloc_address = 0;
-    kernel_alloc_size = 0;
-    kernel_load_address = 0;
-    kernel_load_size = 0;
-    kernel_hdr_size = 0;
-    kernel_hdr_pad = 0;
-    return;
-}
-
-static struct mach_header *
-link_module(const char *filename, const char *output)
-{
-	struct mach_header *rld_header;
-	char *object_addr;
-	long object_size;
-	int ok;
-
-	// Get the address of the thined MachO image.
-	object_addr = kld_file_getaddr(filename, &object_size);
-	if (!object_addr)
-		abort_load(KMOD_ERROR_LOADING, NULL);
-
-	ok = kld_load_from_memory(&rld_header, filename,
-								object_addr, object_size, output);
-	fflush(stdout);
-	if (!ok)
-		abort_load(KMOD_ERROR_LOADING, "kld_load() failed.");
-
-	return rld_header;
-}
-
-// Update the kmod_info_t structure in the image to be laoded
-// Side effect of removing the kKMOD_INFO_SYMBOLNAME from the 
-// loaded symbol name space, otherwise we would have a duplicate
-// defined symbol failure
-vm_address_t
-update_kmod_info(struct mach_header *mach_header)
-{
-	char * symbol = kKMOD_INFO_SYMBOLNAME;
-	kmod_info_t *info;
-	unsigned long value;
-	int ok;
-
-	ok = kld_lookup(symbol, &value); fflush(stdout);
-	if (!ok)
-		abort_load(KMOD_ERROR_LOADING, "kld_lookup(%s) failed.", symbol);
-
-	ok = kld_forget_symbol(symbol); fflush(stdout);
-	if (!ok)
-		abort_load(KMOD_ERROR_LOADING, "kld_forget_symbol(%s) failed.", symbol);
-
-       /* Get the kmod info by translating from the kernel address at value.
-        */
-	info = (kmod_info_t *)(value - (unsigned long)kernel_load_address + (unsigned long)mach_header);
-	v_printf("kmod name: %s", info->name);
-	v_printf("kmod start @ 0x%x", (vm_address_t)info->start);
-	v_printf("kmod stop  @ 0x%x", (vm_address_t)info->stop);
-
-       /* Record link info in kmod info struct, rounding the hdr_size to fit
-        * the adjustment that was made.
-        */
-	info->address = kernel_alloc_address;
-	info->size = kernel_alloc_size;
-	info->hdr_size = page_round(kernel_hdr_size);
-
-	if (!info->start)
-		abort_load(KMOD_ERROR_LOADING, "invalid start address?");
-	else if (!info->stop)
-		abort_load(KMOD_ERROR_LOADING, "invalid stop address?");
-
-	return (vm_address_t)value;
-}
-
-static kmod_t 
-load_module(struct mach_header *mach_header, vm_address_t info)
-{
-    int r;
-    kmod_t id;
-    vm_address_t vm_buffer = 0;
-
-    r = vm_allocate(mach_task_self(), &vm_buffer,
-        kernel_alloc_size, TRUE);
-    macherr(r, "unable to vm_allocate() copy buffer");
-
-   /* Copy the linked segment data into the page-aligned buffer.
-    * Do not round the header size here.
-    */
-    bzero((void *)vm_buffer, kernel_alloc_size);
-    memcpy((void *)vm_buffer, mach_header, kernel_hdr_size);
-    memcpy((void *)vm_buffer + page_round(kernel_hdr_size),
-        (void *)((unsigned long)mach_header + kernel_hdr_size),
-        kernel_load_size - kernel_hdr_size);
-
-    // copy linked header into kernel address space
-    r = vm_write(kernel_port, kernel_alloc_address,
-        vm_buffer, kernel_alloc_size);
-    macherr(r, "unable to write module into kernel memory");
-
-    // let the kernel know about it
-    r = kmod_create(kernel_priv_port, info, &id);
-    macherr(r, "unable to register module with kernel");
-
-    v_printf("kmod id %d successfully created at 0x%x size %ld.\n", 
-        id, kernel_alloc_address, kernel_alloc_size);
-
-    // FIXME: make sure this happens even on failure
-
-    vm_deallocate(mach_task_self(), vm_buffer, kernel_alloc_size);
-    return id;
-}
-
-static void
-set_module_dependencies(kmod_t id)
-{
-	int r;
-	void * args = 0;
-	int argsCount= 0;
-	kmod_info_t *module = module_dependencies;
-
-	while (module) {
-
-		r = kmod_control(kernel_priv_port, KMOD_PACK_IDS(id, module->id), KMOD_CNTL_RETAIN, &args, &argsCount);
-		machwarn(r, "kmod_control(retain) failed");
-		if (r) {
-			clear_globals();
-			r = kmod_destroy(kernel_priv_port, id);
-			macherr(r, "kmod_destroy failed");
-		}
-
-		v_printf("kmod id %d reference count was sucessfully incremented.", module->id);
-
-		module = module->next;
-	}
-}
-
-static void
-start_module(kmod_t id)
-{
-	int r;
-	void * args = 0;
-	int argsCount= 0;
-
-	r = kmod_control(kernel_priv_port, id, KMOD_CNTL_START, &args, &argsCount);
-	machwarn(r, "kmod_control(start) failed");
-	if (r) {
-		clear_globals();
-		kmod_destroy(kernel_priv_port, id);
-		macherr(r, "kmod_destroy failed");
-	}
-
-	v_printf("kmod id %d successfully started.", id);
-}
-
-static void e_printf(const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	kld_error_vprintf(fmt, ap);
-	va_end(ap);
-}
-
-static void v_printf(const char *fmt, ...)
-{
-	va_list ap;
-	char msg[1024];
-
-	if (!verbose) return;
-
-	va_start(ap, fmt);
-	vsnprintf(msg, sizeof(msg), fmt, ap);
-	va_end(ap);
-
-	printf("%s: %s\n", progname, msg);
-}
-
-static void abort_load(int exitcode, const char *fmt, ...)
-{
-	if (fmt) {
-		va_list ap;
-	
-		va_start(ap, fmt);
-		kld_error_vprintf(fmt, ap);
-		va_end(ap);
-	}
-
-	if (!faked_kernel_load_address
-	&& (kernel_alloc_address || kernel_alloc_size)) {	
-		int r;
-
-		v_printf("freeing %ld bytes in kernel space at 0x%x",
-					kernel_alloc_size, kernel_alloc_address);
-		r = vm_deallocate(kernel_port, kernel_alloc_address, kernel_alloc_size);
-		machwarn(r, "unable to cleanup kernel memory");
-	}
-
-	exit(exitcode);
-}
-
-__private_extern__ void
-kld_error_vprintf(const char *fmt, va_list ap)
-{
-    char msg[1024];
-
-    vsnprintf(msg, sizeof(msg), fmt, ap);
-    fprintf(stderr, "%s: %s", progname, msg);
-
-    fflush(stderr);
-}
diff --git a/kmodload.tproj/kmodsyms.8 b/kmodload.tproj/kmodsyms.8
deleted file mode 100644
index f3f18cf..0000000
--- a/kmodload.tproj/kmodsyms.8
+++ /dev/null
@@ -1,105 +0,0 @@
-.\"
-.\" Copyright (c) 1997 Doug Rabson
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\"	$Id: kmodsyms.8,v 1.2 2000/02/24 22:31:35 lindak Exp $
-.\"
-.Dd April 8, 1999
-.Dt KMODSYMS 8
-.Os FreeBSD
-.Sh NAME
-.Nm kmodsyms
-.Nd creates a statically linked symbol file for remote debugging
-.Sh SYNOPSIS
-.Nm kmodsyms
-.Op Fl v
-.Op Fl k Ar kernelfile
-.Op Fl d Ar dependencyfile
-.Fl o Ar symbolfile
-.Ar modulefile
-.Nm kmodsyms
-.Op Fl v
-.Fl k Ar kernelfile
-.Op Fl d Ar dependencyfile@address
-.Fl o Ar symbolfile
-.Ar modulefile@address
-.Sh DESCRIPTION
-The
-.Nm
-creates a statically linked symbol file for remote debugging using
-.Ar modulefile[@address] .
-If an address is specified for either the
-.Ar modulefile
-or
-.Ar dependacyfile
-they both must have the address tag. If addresses are specified it assumed that the command is being run on a different machine with a potentially different kernel, thus the
-.Ar kernelfile
-argument is also required.
-If addresses are not specified they taken from the currently running host machine.
-.Pp
-The following options are available:
-.Bl -tag -width indent
-.It Fl v
-Be more verbose.
-.It Fl k Ar kernelfile
-Use alternate file
-.Ar kernelfile
-instead of default file /mach for linking
-.Ar modulefile .
-.It Fl d Ar dependacyfile[@address]
-Add symbols from
-.Ar dependacyfile
-to kernel symbols prior to linking of
-.Ar modulefile .
-The file 
-.Ar dependacyfile
-must already be loaded.
-.It Fl o Ar symbolfile
-Creates file named
-.Ar symbolfile
-that contains statically linked output suitable to use with
-.Xr gdb 1 
-for remote debugging.
-.El
-.Sh FILES
-.Bl -tag -width /modules -compact
-.It Pa /System/Library/Extensions
-directory containing loadable kernel modules.
-.Sh DIAGNOSTICS
-The
-.Nm
-utility exits with a status of 0 on success. 
-A status of 1 indicates a usage error.
-A status of 2 indicates a indicates a permissions error.
-A status of 3 indicates a problem with linking the module.
-A status of 4 indicates a internal or system error.
-.Sh SEE ALSO
-.Xr kmodload 8 ,
-.Xr kmodstat 8 ,
-.Xr kmodunload 8
-.Sh HISTORY
-The
-.Nm
-command is based on the command kldload written by
-.An Doug Rabson Aq dfr@FreeBSD.org
diff --git a/kmodstat.tproj/Makefile b/kmodstat.tproj/Makefile
deleted file mode 100644
index 2c9f9ed..0000000
--- a/kmodstat.tproj/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Generated by the NeXT Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = kmodstat
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Tool
-
-CFILES = kmodstat.c
-
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble kmodstat.8
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /usr/sbin
-WINDOWS_INSTALLDIR = /Library/Executables
-PDO_UNIX_INSTALLDIR = /bin
-LIBS = 
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-
-
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
-
-include $(MAKEFILEDIR)/platform.make
-
--include Makefile.preamble
-
-include $(MAKEFILEDIR)/$(MAKEFILE)
-
--include Makefile.postamble
-
--include Makefile.dependencies
diff --git a/kmodstat.tproj/Makefile.preamble b/kmodstat.tproj/Makefile.preamble
deleted file mode 100644
index c1624b4..0000000
--- a/kmodstat.tproj/Makefile.preamble
+++ /dev/null
@@ -1,137 +0,0 @@
-###############################################################################
-#  Makefile.preamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile for configuring the standard application makefiles 
-#  associated with ProjectBuilder. It is included before the main makefile.
-#  In Makefile.preamble you set attributes for a project, so they are available
-#  to the project's makefiles.  In contrast, you typically write additional rules or 
-#  override built-in behavior in the Makefile.postamble.
-#  
-#  Each directory in a project tree (main project plus subprojects) should 
-#  have its own Makefile.preamble and Makefile.postamble.
-###############################################################################
-#
-# Before the main makefile is included for this project, you may set:
-#
-#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
-#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
-
-# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
-# inherited by all nested sub-projects, but the LOCAL_ versions of the same
-# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
-# Build Attributes inspector if at all possible.  To override the default flags
-# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
-# variables below are *inputs* to the build process and distinct from the override
-# settings done (less often) in the Makefile.postamble.
-#
-#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
-#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
-#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
-#	flags in OTHER_MFLAGS, etc.
-#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
-#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
-#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
-#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
-#	precompiling header files
-#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
-#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
-#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
-#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
-#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
-
-# These variables provide hooks enabling you to add behavior at almost every 
-# stage of the make:
-#
-#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
-#    AFTER_PREBUILD: targets to build after installing headers for a subproject
-#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
-#    BEFORE_BUILD: targets to make before a build, but after subprojects
-#    AFTER_BUILD: targets to make after a build
-#
-#    BEFORE_INSTALL: targets to build before installing the product
-#    AFTER_INSTALL: targets to build after installing the product
-#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
-#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
-#
-#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
-#         subproject
-#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
-#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
-#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
-#
-#    BEFORE_DEPEND: targets to build before building dependencies for a
-#	  subproject
-#    AFTER_DEPEND: targets to build after building dependencies for a
-#	  subproject
-#
-#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
-#	  updated every time the project is built.  If NO, the dependency
-#	  file is only built when the depend target is invoked.
-
-# Framework-related variables:
-#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the framework's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-
-# Library-related variables:
-#    PUBLIC_HEADER_DIR:  Determines where public exported header files
-#	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.  For library projects you should
-#       set this to something like /Developer/Headers/$(NAME).  Do not set
-#       this variable for framework projects unless you do not want the
-#       header files included in the framework.
-#    PRIVATE_HEADER_DIR:  Determines where private exported header files
-#  	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.
-#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
-#  	whether the libraries produced are statically linked when they
-#	are used or if they are dynamically loadable. This defaults to
-#       DYNAMIC.
-#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the library's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-#
-#    INSTALL_AS_USER: owner of the intalled products (default root)
-#    INSTALL_AS_GROUP: group of the installed products (default wheel)
-#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
-#
-#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
-#  	passed on the command line to recursive invocations of make.  Note that
-#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
-#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
-#	OTHER_RECURSIVE_VARIABLES. 
-
-# Additional headers to export beyond those in the PB.project:
-#    OTHER_PUBLIC_HEADERS
-#    OTHER_PROJECT_HEADERS
-#    OTHER_PRIVATE_HEADERS
-
-# Additional files for the project's product: <<path relative to proj?>>
-#    OTHER_RESOURCES: (non-localized) resources for this project
-#    OTHER_OFILES: relocatables to be linked into this project
-#    OTHER_LIBS: more libraries to link against
-#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
-#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
-#    OTHER_GARBAGE: additional files to be removed by `make clean'
-
-# Set this to YES if you don't want a final libtool call for a library/framework.
-#    BUILD_OFILES_LIST_ONLY
-
-# To include a version string, project source must exist in a directory named 
-# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
-# OTHER_GENERATED_OFILES = $(VERS_OFILE)
-
-# This definition will suppress stripping of debug symbols when an executable
-# is installed.  By default it is YES.
-# STRIP_ON_INSTALL = NO
-
-# Uncomment to suppress generation of a KeyValueCoding index when installing 
-# frameworks (This index is used by WOB and IB to determine keys available
-# for an object).  Set to YES by default.
-# PREINDEX_FRAMEWORK = NO
-
-# Change this definition to install projects somewhere other than the
-# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
-# and "" on other systems.
-DSTROOT = $(HOME)
diff --git a/kmodstat.tproj/PB.project b/kmodstat.tproj/PB.project
deleted file mode 100644
index 8e9b705..0000000
--- a/kmodstat.tproj/PB.project
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-    DYNAMIC_CODE_GEN = YES; 
-    FILESTABLE = {
-        FRAMEWORKS = (); 
-        OTHER_LINKED = (kmodstat.c); 
-        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, kmodstat.8); 
-    }; 
-    LANGUAGE = English; 
-    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
-    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
-    NEXTSTEP_INSTALLDIR = /usr/sbin; 
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
-    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
-    PDO_UNIX_INSTALLDIR = /bin; 
-    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
-    PROJECTNAME = kmodstat; 
-    PROJECTTYPE = Tool; 
-    PROJECTVERSION = 2.8; 
-    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
-    WINDOWS_INSTALLDIR = /Library/Executables; 
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
-}
diff --git a/kmodstat.tproj/kmodstat.c b/kmodstat.tproj/kmodstat.c
deleted file mode 100644
index 2f39c73..0000000
--- a/kmodstat.tproj/kmodstat.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1997 Doug Rabson
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Original code from:
- *	"kldstat.c,v 1.5 1998/11/07 00:29:09 des Exp";
- */
-
-#ifndef lint
-static const char rcsid[] =
-	"$Id: kmodstat.c,v 1.3 2000/04/26 21:27:57 lindak Exp $";
-#endif /* not lint */
-
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/param.h>
-
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <mach/mach_host.h>
-
-static void
-machwarn(int error, const char *message)
-{
-	if (error == KERN_SUCCESS) return;
-	fprintf(stderr, "kmodstat: %s: %s\n", message, mach_error_string(error));
-}
-
-static void
-macherr(int error, const char *message)
-{
-	if (error == KERN_SUCCESS) return;
-	fprintf(stderr, "kmodstat: %s: %s\n", message, mach_error_string(error));
-	exit(1);
-}
-
-static int
-kmod_compare(const void *a, const void *b)
-{
-	return (((kmod_info_t *)a)->id - ((kmod_info_t *)b)->id);
-}
-
-static void
-usage(void)
-{
-	fprintf(stderr, "usage: kmodstat [-i id] [-n name]\n");
-	exit(1);
-}
-
-int
-main(int argc, char** argv)
-{
-	int c, idset = 0, id = 0;
-	char* name = 0;
-	kmod_info_t *info, *k;
-	kmod_reference_t *r;
-	int i, j, rc, foundit, count, rcount;
-	mach_port_t kernel_port;
-
-	while ((c = getopt(argc, argv, "i:n:")) != -1)
-		switch (c) {
-		case 'i':
-			idset++;
-			id = atoi(optarg);
-			break;
-		case 'n':
-			name = optarg;
-			break;
-		default:
-			usage();
-		}
-	argc -= optind;
-	argv += optind;
-
-	if (!idset && !name && (argc == 1)) {
-		name = *argv;
-		argc--;
-	}
-    
-	if (argc != 0) usage();
-
-	rc = task_for_pid(mach_task_self(), 0, &kernel_port);
-	machwarn(rc, "unable to get kernel task port");
-	if (rc) {
-		fprintf(stderr, "kmodstat: Are you running as root?\n");
-		exit(1);
-	}
-
-	rc= kmod_get_info(kernel_port, (void *)&info, &count);
-	macherr(rc, "kmod_get_info() failed");
-
-	k = info; count = 0;
-	while (k) {
-		count++;
-		k  = (k->next) ? (k + 1) : 0;
-	}
-
-	k = info; r = (kmod_reference_t *)(info + count);
-	while (k) {
-		if ((rcount = (int)k->reference_list)) {
-			k->reference_list = r;
-			for (i=0; i < rcount; i++) {
-				foundit = 0;
-				for (j=0; j < count; j++) {
-					if (r->info == info[j].next) {
-						r->info = (kmod_info_t *)info[j].id;
-						foundit++;
-						break;
-					}
-				}
-				// force the id in here, the sorting below messes up the pointers
-				if (!foundit) r->info = (kmod_info_t *)info[count - 1].id;
-				r->next = r + 1;
-				r++;
-			}
-			k->reference_list[rcount - 1].next = 0;
-		}
-		k  = (k->next) ? (k + 1) : 0;
-	}
-
-	printf("Id Refs Address    Size       Wired      Name (Version) <Linked Against>\n");
-
-	if (!count) return 0;
-
-	qsort(info, count, sizeof(kmod_info_t), kmod_compare);
-
-	if (idset || name) {
-		kmod_info_t *k = info;
-		int match_count = 0;
-		for (i=0; i < count; i++, k++) {
-			if ((idset && id == k->id) || (name && !strcmp(k->name, name))) {
-				info[match_count++] = *k;
-			}
-		}
-		count = match_count;
-	} 
-	for (i=0; i < count; i++, info++) {
-		printf("%2d %4d %-10p %-10p %-10p %s (%s)",
-		       info->id, info->reference_count, (void *)info->address, 
-		       (void *)info->size, (void *)(info->size - info->hdr_size),
-		       info->name, info->version);
-
-		if ((r = info->reference_list)) {
-			printf(" <%d", (int)r->info);
-			r = r->next;
-			while (r) {
-				printf(" %d", (int)r->info);
-				r = r->next;
-			}
-			printf(">");
-		}
-		printf("\n");
-	}
-
-	return 0;
-}
diff --git a/kmodunload.tproj/Makefile b/kmodunload.tproj/Makefile
deleted file mode 100644
index 1700393..0000000
--- a/kmodunload.tproj/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Generated by the NeXT Project Builder.
-#
-# NOTE: Do NOT change this file -- Project Builder maintains it.
-#
-# Put all of your customizations in files called Makefile.preamble
-# and Makefile.postamble (both optional), and Makefile will include them.
-#
-
-NAME = kmodunload
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Tool
-
-CFILES = kmodunload.c
-
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble kmodunload.8
-
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = tool.make
-NEXTSTEP_INSTALLDIR = /sbin
-WINDOWS_INSTALLDIR = /Library/Executables
-PDO_UNIX_INSTALLDIR = /bin
-LIBS = 
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-
-
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
-WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
-PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
-NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
-WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
-PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
-
-include $(MAKEFILEDIR)/platform.make
-
--include Makefile.preamble
-
-include $(MAKEFILEDIR)/$(MAKEFILE)
-
--include Makefile.postamble
-
--include Makefile.dependencies
diff --git a/kmodunload.tproj/Makefile.postamble b/kmodunload.tproj/Makefile.postamble
deleted file mode 100644
index c2d62c5..0000000
--- a/kmodunload.tproj/Makefile.postamble
+++ /dev/null
@@ -1,106 +0,0 @@
-###############################################################################
-#  Makefile.postamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile, which is imported after all other makefiles, to
-#  override attributes for a project's Makefile environment. This allows you  
-#  to take advantage of the environment set up by the other Makefiles. 
-#  You can also define custom rules at the end of this file.
-#
-###############################################################################
-# 
-# These variables are exported by the standard makefiles and can be 
-# used in any customizations you make.  They are *outputs* of
-# the Makefiles and should be used, not set.
-# 
-#  PRODUCTS: products to install.  All of these products will be placed in
-#	 the directory $(DSTROOT)$(INSTALLDIR)
-#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
-#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
-#  OFILE_DIR: Directory into which .o object files are generated.
-#  DERIVED_SRC_DIR: Directory used for all other derived files
-#
-#  ALL_CFLAGS:  flags to pass when compiling .c files
-#  ALL_MFLAGS:  flags to pass when compiling .m files
-#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
-#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
-#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
-#  ALL_LDFLAGS:  flags to pass when linking object files
-#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
-#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
-#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
-#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
-#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
-#
-#  NAME: name of application, bundle, subproject, palette, etc.
-#  LANGUAGES: langages in which the project is written (default "English")
-#  English_RESOURCES: localized resources (e.g. nib's, images) of project
-#  GLOBAL_RESOURCES: non-localized resources of project
-#
-#  SRCROOT:  base directory in which to place the new source files
-#  SRCPATH:  relative path from SRCROOT to present subdirectory
-#
-#  INSTALLDIR: Directory the product will be installed into by 'install' target
-#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
-#        to prefix this with DSTROOT when you use it.
-#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
-#	 to prefix this with DSTROOT when you use it.
-#
-#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
-#
-###############################################################################
-
-# Some compiler flags can be overridden here for certain build situations.
-#
-#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
-#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
-#	to -g)
-#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
-#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
-#	to -O)
-#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
-#	to -pg -DPROFILE)
-#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
-#	the include path (defaults to -I.)
-#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
-#	passed to ld/libtool (defaults to nothing)
-
-
-# Library and Framework projects only:
-#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
-#	against the framework will run against the correct version even if
-#	the current version of the framework changes.  You may override this
-#	to "" as an alternative to using the DYLD_LIBRARY_PATH during your
-#	development cycle, but be sure to restore it before installing.
-
-
-# Ownership and permissions of files installed by 'install' target
-
-#INSTALL_AS_USER = root
-        # User/group ownership 
-#INSTALL_AS_GROUP = wheel
-        # (probably want to set both of these) 
-#INSTALL_PERMISSIONS =
-        # If set, 'install' chmod's executable to this
-
-
-# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
-# down further with -x or, if they load no bundles, with no options at all).
-
-#STRIPFLAGS = -S
-
-
-#########################################################################
-# Put rules to extend the behavior of the standard Makefiles here.  Include them in
-# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
-#
-# You should avoid redefining things like "install" or "app", as they are
-# owned by the top-level Makefile API and no context has been set up for where 
-# derived files should go.
-#
-
-after_install::
-	-mkdir -p ${DSTROOT}/usr/share/man/man8
-	-rm -f ${DSTROOT}/usr/share/man/man8/kmodunload.8
-	cp kmodunload.8 ${DSTROOT}/usr/share/man/man8/kmodunload.8
-	chmod og-w ${DSTROOT}/usr/share/man/man8/kmodunload.8
diff --git a/kmodunload.tproj/Makefile.preamble b/kmodunload.tproj/Makefile.preamble
deleted file mode 100644
index c1624b4..0000000
--- a/kmodunload.tproj/Makefile.preamble
+++ /dev/null
@@ -1,137 +0,0 @@
-###############################################################################
-#  Makefile.preamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile for configuring the standard application makefiles 
-#  associated with ProjectBuilder. It is included before the main makefile.
-#  In Makefile.preamble you set attributes for a project, so they are available
-#  to the project's makefiles.  In contrast, you typically write additional rules or 
-#  override built-in behavior in the Makefile.postamble.
-#  
-#  Each directory in a project tree (main project plus subprojects) should 
-#  have its own Makefile.preamble and Makefile.postamble.
-###############################################################################
-#
-# Before the main makefile is included for this project, you may set:
-#
-#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
-#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
-
-# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
-# inherited by all nested sub-projects, but the LOCAL_ versions of the same
-# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
-# Build Attributes inspector if at all possible.  To override the default flags
-# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
-# variables below are *inputs* to the build process and distinct from the override
-# settings done (less often) in the Makefile.postamble.
-#
-#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
-#	Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
-#	.cc, .cxx, .C, and .M files.  There is no need to respecify the
-#	flags in OTHER_MFLAGS, etc.
-#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
-#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
-#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
-#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
-#	precompiling header files
-#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
-#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
-#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
-#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
-#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
-
-# These variables provide hooks enabling you to add behavior at almost every 
-# stage of the make:
-#
-#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
-#    AFTER_PREBUILD: targets to build after installing headers for a subproject
-#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
-#    BEFORE_BUILD: targets to make before a build, but after subprojects
-#    AFTER_BUILD: targets to make after a build
-#
-#    BEFORE_INSTALL: targets to build before installing the product
-#    AFTER_INSTALL: targets to build after installing the product
-#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
-#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
-#
-#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
-#         subproject
-#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
-#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
-#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
-#
-#    BEFORE_DEPEND: targets to build before building dependencies for a
-#	  subproject
-#    AFTER_DEPEND: targets to build after building dependencies for a
-#	  subproject
-#
-#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
-#	  updated every time the project is built.  If NO, the dependency
-#	  file is only built when the depend target is invoked.
-
-# Framework-related variables:
-#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the framework's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-
-# Library-related variables:
-#    PUBLIC_HEADER_DIR:  Determines where public exported header files
-#	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.  For library projects you should
-#       set this to something like /Developer/Headers/$(NAME).  Do not set
-#       this variable for framework projects unless you do not want the
-#       header files included in the framework.
-#    PRIVATE_HEADER_DIR:  Determines where private exported header files
-#  	should be installed.  Do not include $(DSTROOT) in this value --
-#	it is prefixed automatically.
-#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
-#  	whether the libraries produced are statically linked when they
-#	are used or if they are dynamically loadable. This defaults to
-#       DYNAMIC.
-#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#	where to put the library's DLL.  This variable defaults to 
-#	$(INSTALLDIR)/../Executables
-#
-#    INSTALL_AS_USER: owner of the intalled products (default root)
-#    INSTALL_AS_GROUP: group of the installed products (default wheel)
-#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
-#
-#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
-#  	passed on the command line to recursive invocations of make.  Note that
-#	the values in OTHER_*FLAGS are inherited by subprojects automatically --
-#	you do not have to (and shouldn't) add OTHER_*FLAGS to 
-#	OTHER_RECURSIVE_VARIABLES. 
-
-# Additional headers to export beyond those in the PB.project:
-#    OTHER_PUBLIC_HEADERS
-#    OTHER_PROJECT_HEADERS
-#    OTHER_PRIVATE_HEADERS
-
-# Additional files for the project's product: <<path relative to proj?>>
-#    OTHER_RESOURCES: (non-localized) resources for this project
-#    OTHER_OFILES: relocatables to be linked into this project
-#    OTHER_LIBS: more libraries to link against
-#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
-#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
-#    OTHER_GARBAGE: additional files to be removed by `make clean'
-
-# Set this to YES if you don't want a final libtool call for a library/framework.
-#    BUILD_OFILES_LIST_ONLY
-
-# To include a version string, project source must exist in a directory named 
-# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
-# OTHER_GENERATED_OFILES = $(VERS_OFILE)
-
-# This definition will suppress stripping of debug symbols when an executable
-# is installed.  By default it is YES.
-# STRIP_ON_INSTALL = NO
-
-# Uncomment to suppress generation of a KeyValueCoding index when installing 
-# frameworks (This index is used by WOB and IB to determine keys available
-# for an object).  Set to YES by default.
-# PREINDEX_FRAMEWORK = NO
-
-# Change this definition to install projects somewhere other than the
-# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
-# and "" on other systems.
-DSTROOT = $(HOME)
diff --git a/kmodunload.tproj/PB.project b/kmodunload.tproj/PB.project
deleted file mode 100644
index 7d909c1..0000000
--- a/kmodunload.tproj/PB.project
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-    DYNAMIC_CODE_GEN = YES; 
-    FILESTABLE = {
-        FRAMEWORKS = (); 
-        OTHER_LINKED = (kmodunload.c); 
-        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, kmodunload.8); 
-    }; 
-    LANGUAGE = English; 
-    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
-    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
-    NEXTSTEP_INSTALLDIR = /sbin; 
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
-    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
-    PDO_UNIX_INSTALLDIR = /bin; 
-    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
-    PROJECTNAME = kmodunload; 
-    PROJECTTYPE = Tool; 
-    PROJECTVERSION = 2.8; 
-    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
-    WINDOWS_INSTALLDIR = /Library/Executables; 
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
-}
diff --git a/kmodunload.tproj/kmodunload.8 b/kmodunload.tproj/kmodunload.8
deleted file mode 100644
index 358030c..0000000
--- a/kmodunload.tproj/kmodunload.8
+++ /dev/null
@@ -1,69 +0,0 @@
-.\"
-.\" Copyright (c) 1997 Doug Rabson
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\"	$Id: kmodunload.8,v 1.1.1.1 2000/01/11 02:10:18 wsanchez Exp $
-.\"
-.Dd April 8, 1999
-.Dt KMODUNLOAD 8
-.Os FreeBSD
-.Sh NAME
-.Nm kmodunload
-.Nd stops and unloads a kernel module
-.Sh SYNOPSIS
-.Nm kmodunload
-.Op Fl v
-.Fl i Ar id
-.Nm kmodunload
-.Op Fl v
-.Fl n Ar name
-.Sh DESCRIPTION
-The
-.Nm
-utility stops and unloads a kernel module which was previously loaded with
-.Xr kmodload 8 .
-.Pp
-The following options are available:
-.Bl -tag -width indentXX
-.It Fl v
-Be more verbose.
-.It Fl i Ar id
-Unload the kernel module with this ID.
-.It Fl n Ar name
-Unload the kernel module with this name.
-.El
-.Sh DIAGNOSTICS
-The
-.Nm
-utility exits with a status of 0 on success
-and with a nonzero status if an error occurs.
-.Sh SEE ALSO
-.Xr kmodload 8 ,
-.Xr kmodstat 8 ,
-.Xr kmodsyms 8
-.Sh HISTORY
-The
-.Nm
-command is based on the command kldunload written by
-.An Doug Rabson Aq dfr@FreeBSD.org
diff --git a/kmodunload.tproj/kmodunload.c b/kmodunload.tproj/kmodunload.c
deleted file mode 100644
index 4fb96b0..0000000
--- a/kmodunload.tproj/kmodunload.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1997 Doug Rabson
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Original code from:
- *	"kldunload.c,v 1.7 1998/11/07 00:42:52 des Exp"
- */
-
-#ifndef lint
-static const char rcsid[] =
-	"$Id: kmodunload.c,v 1.3 2001/02/05 19:53:16 lindak Exp $";
-#endif /* not lint */
-
-#include <err.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <mach/mach_host.h>
-
-static int verbose = 0;
-#define v_printf	if (verbose) printf
-
-static void
-machwarn(int error, const char *message)
-{
-	if (error == KERN_SUCCESS) return;
-	fprintf(stderr, "kmodunload: %s: %s\n", message, mach_error_string(error));
-}
-
-static void
-macherr(int error, const char *message)
-{
-	if (error == KERN_SUCCESS) return;
-	fprintf(stderr, "kmodunload: %s: %s\n", message, mach_error_string(error));
-	exit(1);
-}
-
-static mach_port_t kernel_priv_port;
-
-static void
-stop_module(kmod_t id)
-{
-	int r;
-	void * args = 0;
-	int argsCount= 0;
-
-	r = kmod_control(kernel_priv_port, id, KMOD_CNTL_STOP, &args, &argsCount);
-	macherr(r, "kmod_control(stop) failed");
-
-	v_printf("kmodunload: kmod id %d successfully stopped.\n", id);
-}
-
-static void
-unload_module(kmod_t id)
-{
-	int r;
-
-	r = kmod_destroy(kernel_priv_port, id);
-	macherr(r, "kmod_destroy() failed");
-
-	v_printf("kmodunload: kmod id %d successfully unloaded.\n", id);
-}
-
-static void
-usage(void)
-{
-	fprintf(stderr, "usage: kmodunload [-v] -i id\n");
-	fprintf(stderr, "       kmodunload [-v] -n name\n");
-	exit(1);
-}
-
-int
-main(int argc, char** argv)
-{
-	int c;
-	int id = 0;
-	char* name = 0;
-	kmod_info_t *info;
-	int r;
-	int count;
-	mach_port_t kernel_port;
-
-	while ((c = getopt(argc, argv, "i:n:v")) != -1)
-		switch (c) {
-		case 'i':
-			id = atoi(optarg);
-			break;
-		case 'n':
-			name = optarg;
-			break;
-		case 'v':
-			verbose = 1;
-			break;
-		default:
-			usage();
-		}
-	argc -= optind;
-	argv += optind;
-
-	if (!id && !name && (argc == 1)) {
-		name = *argv;
-		argc--;
-	}
-    
-	if ((argc != 0) || (id && name))
-		usage();
-
-	if ((id == 0) && (name == 0))
-		usage();
-
-	r = task_for_pid(mach_task_self(), 0, &kernel_port);
-	machwarn(r, "unable to get kernel task port");
-	if (r) {
-		fprintf(stderr, "kmodunload: Are you running as root?\n");
-		exit(1);
-	}
-
-	r = kmod_get_info(kernel_port, (void *)&info, &count);
-	macherr(r, "kmod_get_info() failed");
-
-	if (count < 1) {
-		fprintf(stderr, "kmodunload: there is nothing to unload?\n");
-		exit(1);
-	}
-
-	if (name) {
-		kmod_info_t *k = info;
-		while (k) {
-			if (!strcmp(k->name, name)) {
-				id = k->id;
-				break;
-			}
-			k = (k->next) ? (k + 1) : 0;
-		}
-		if (!k) {
-			fprintf(stderr, "kmodunload: can't kmod named: %s.\n", name);
-			exit(1);
-		}
-	} else {
-		kmod_info_t *k = info;
-		while (k) {
-			if (id == k->id) {
-				name = k->name;
-				break;
-			}
-			k = (k->next) ? (k + 1) : 0;
-		}
-		if (!name) {
-			fprintf(stderr, "kmodunload: can't find kmod id %d.\n", id);
-			exit(1);
-		}
-	}
-	
-	v_printf("kmodunload: found kmod %s, id %d.\n", name, id);
-	kernel_priv_port = mach_host_self(); /* if we are privileged */
-
-	stop_module(id);
-	unload_module(id);
-
-	return 0;
-}
-
diff --git a/ktrace.tproj/Makefile b/ktrace.tproj/Makefile
index 6369360..254b43a 100644
--- a/ktrace.tproj/Makefile
+++ b/ktrace.tproj/Makefile
@@ -16,7 +16,7 @@ HFILES = ktrace.h
 
 CFILES = ktrace.c subr.c
 
-OTHERSRCS = Makefile.preamble Makefile ktrace.1
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble ktrace.1
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
diff --git a/ktrace.tproj/Makefile.postamble b/ktrace.tproj/Makefile.postamble
new file mode 100644
index 0000000..f7143e4
--- /dev/null
+++ b/ktrace.tproj/Makefile.postamble
@@ -0,0 +1,4 @@
+install-man-page:
+	install -d $(DSTROOT)/usr/share/man/man1
+	install -c -m 444 ktrace.1 $(DSTROOT)/usr/share/man/man1/ktrace.1
+
diff --git a/ktrace.tproj/Makefile.preamble b/ktrace.tproj/Makefile.preamble
index d5059b1..de796ce 100644
--- a/ktrace.tproj/Makefile.preamble
+++ b/ktrace.tproj/Makefile.preamble
@@ -1,2 +1,3 @@
 OTHER_GENERATED_OFILES = $(VERS_OFILE)
+AFTER_INSTALL += install-man-page
 
diff --git a/ktrace.tproj/PB.project b/ktrace.tproj/PB.project
index c0b395a..1a3d2e9 100644
--- a/ktrace.tproj/PB.project
+++ b/ktrace.tproj/PB.project
@@ -8,7 +8,7 @@
         M_FILES = (); 
         OTHER_LIBS = (); 
         OTHER_LINKED = (ktrace.c, subr.c); 
-        OTHER_SOURCES = (Makefile.preamble, Makefile, ktrace.1); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, ktrace.1); 
         SUBPROJECTS = (); 
     }; 
     LANGUAGE = English; 
diff --git a/ktrace.tproj/ktrace.1 b/ktrace.tproj/ktrace.1
index d080b4e..082e34b 100644
--- a/ktrace.tproj/ktrace.1
+++ b/ktrace.tproj/ktrace.1
@@ -30,28 +30,29 @@
 .\" SUCH DAMAGE.
 .\"
 .\"	@(#)ktrace.1	8.1 (Berkeley) 6/6/93
+.\" $FreeBSD: src/usr.bin/ktrace/ktrace.1,v 1.8.2.5 2001/08/16 13:16:53 ru Exp $
 .\"
 .Dd June 6, 1993
 .Dt KTRACE 1
-.Os BSD 4.4
+.Os
 .Sh NAME
 .Nm ktrace
 .Nd enable kernel process tracing
 .Sh SYNOPSIS
-.Nm ktrace
+.Nm
 .Op Fl aCcdi
 .Op Fl f Ar trfile
-.Op Fl g Ar pgrp
-.Op Fl p Ar pid
+.Op Fl g Ar pgrp | Fl p Ar pid
 .Op Fl t Ar trstr
-.Nm ktrace
+.Nm
 .Op Fl adi
 .Op Fl f Ar trfile
 .Op Fl t Ar trstr
-command
+.Ar command
 .Sh DESCRIPTION
-.Nm Ktrace
-enables kernel trace logging for the specified processes.
+The
+.Nm
+command enables kernel trace logging for the specified processes.
 Kernel trace data is logged to the file
 .Pa ktrace.out .
 The kernel operations that are traced include system calls, namei
@@ -66,7 +67,7 @@ attempting to trace a process.
 The following command is sufficient to disable tracing on all user owned
 processes, and, if executed by root, all processes:
 .Pp
-.Dl \&$ trace -C
+.Dl \&$ ktrace -C
 .Pp
 The trace file is not human readable; use
 .Xr kdump 1
@@ -75,7 +76,7 @@ to decode it.
 The options are as follows:
 .Bl -tag -width indent
 .It Fl a
-Append to the trace file instead of truncating it.
+Append to the trace file instead of recreating it.
 .It Fl C
 Disable tracing on all user owned processes, and, if executed by root, all
 processes in the system.
@@ -84,23 +85,23 @@ Clear the trace points associated with the specified file or processes.
 .It Fl d
 Descendants; perform the operation for all current children of the
 designated processes.
-.It Fl f Ar file 
+.It Fl f Ar file
 Log trace records to
 .Ar file
 instead of
 .Pa ktrace.out .
-.It Fl g Ar pgid 
+.It Fl g Ar pgid
 Enable (disable) tracing on all processes in the process group (only one
 .Fl g
 flag is permitted).
 .It Fl i
 Inherit; pass the trace flags to all future children of the designated
 processes.
-.It Fl p Ar pid 
+.It Fl p Ar pid
 Enable (disable) tracing on the indicated process id (only one
 .Fl p
 flag is permitted).
-.It Fl t Ar trstr 
+.It Fl t Ar trstr
 The string argument represents the kernel trace points, one per letter.
 The following table equates the letters with the tracepoints:
 .Pp
@@ -114,6 +115,10 @@ trace
 .Tn I/O
 .It Cm s
 trace signal processing
+.It Cm u
+userland traces
+.It Cm w
+context switches
 .El
 .It Ar command
 Execute
@@ -156,8 +161,12 @@ on process 67
 .Dl $ ktrace -C
 .Sh SEE ALSO
 .Xr kdump 1
+.Sh BUGS
+Only works if
+.Ar file
+is a regular file.
 .Sh HISTORY
 The
-.Nm ktrace
-command appears in
+.Nm
+command appeared in
 .Bx 4.4 .
diff --git a/ktrace.tproj/ktrace.c b/ktrace.tproj/ktrace.c
index 188e9ba..dc09649 100644
--- a/ktrace.tproj/ktrace.c
+++ b/ktrace.tproj/ktrace.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999, 2000-2001 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -23,7 +23,7 @@
  */
 /*-
  * Copyright (c) 1988, 1993
- *      The Regents of the University of California.  All rights reserved.
+ *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,8 +35,8 @@
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
- *      This product includes software developed by the University of
- *      California, Berkeley and its contributors.
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -54,6 +54,20 @@
  * SUCH DAMAGE.
  */
 
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ktrace.c	8.1 (Berkeley) 6/6/93";
+#endif
+static const char rcsid[] =
+  "$FreeBSD: src/usr.bin/ktrace/ktrace.c,v 1.12.2.3 2001/07/11 00:29:27 mikeh Exp $";
+#endif /* not lint */
+
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/file.h>
@@ -64,7 +78,6 @@
 
 #include <err.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <unistd.h>
 
 #include "ktrace.h"
@@ -79,12 +92,14 @@ main(argc, argv)
 	enum { NOTSET, CLEAR, CLEARALL } clear;
 	int append, ch, fd, inherit, ops, pid, pidset, trpoints;
 	char *tracefile;
+	mode_t omask;
+	struct stat sb;
 
 	clear = NOTSET;
 	append = ops = pidset = inherit = 0;
 	trpoints = DEF_POINTS;
 	tracefile = DEF_TRACEFILE;
-	while ((ch = getopt(argc,argv,"aCcdf:g:ip:t:")) != EOF)
+	while ((ch = getopt(argc,argv,"aCcdf:g:ip:t:")) != -1)
 		switch((char)ch) {
 		case 'a':
 			append = 1;
@@ -139,26 +154,38 @@ main(argc, argv)
 			trpoints = ALL_POINTS;
 			pid = 1;
 		} else
-			ops |= pid ? KTROP_CLEAR : KTROP_CLEARFILE;
+			ops |= pidset ? KTROP_CLEAR : KTROP_CLEARFILE;
 
 		if (ktrace(tracefile, ops, trpoints, pid) < 0)
-			err(1, tracefile);
+			err(1, "%s", tracefile);
 		exit(0);
 	}
 
-	if ((fd = open(tracefile, O_CREAT | O_WRONLY | (append ? 0 : O_TRUNC),
-	    DEFFILEMODE)) < 0)
-		err(1, tracefile);
+	omask = umask(S_IRWXG|S_IRWXO);
+	if (append) {
+		if ((fd = open(tracefile, O_CREAT | O_WRONLY, DEFFILEMODE)) < 0)
+			err(1, "%s", tracefile);
+		if (fstat(fd, &sb) != 0 || sb.st_uid != getuid())
+			errx(1, "Refuse to append to %s not owned by you.",
+			    tracefile);
+	} else {
+		if (unlink(tracefile) == -1 && errno != ENOENT)
+			err(1, "unlink %s", tracefile);
+		if ((fd = open(tracefile, O_CREAT | O_EXCL | O_WRONLY,
+		    DEFFILEMODE)) < 0)
+			err(1, "%s", tracefile);
+	}
+	(void)umask(omask);
 	(void)close(fd);
 
 	if (*argv) { 
 		if (ktrace(tracefile, ops, trpoints, getpid()) < 0)
-			err(1, tracefile);
+			err(1, "%s", tracefile);
 		execvp(argv[0], &argv[0]);
 		err(1, "exec of '%s' failed", argv[0]);
 	}
 	else if (ktrace(tracefile, ops, trpoints, pid) < 0)
-		err(1, tracefile);
+		err(1, "%s", tracefile);
 	exit(0);
 }
 
@@ -181,8 +208,9 @@ rpid(p)
 void
 usage()
 {
-	(void)fprintf(stderr,
-"usage:\tktrace [-aCcid] [-f trfile] [-g pgid] [-p pid] [-t [acgn]\n\tktrace [-aCcid] [-f trfile] [-t [acgn] command\n");
+	(void)fprintf(stderr, "%s\n%s\n",
+"usage: ktrace [-aCcdi] [-f trfile] [-g pgrp | -p pid] [-t cnisuw]",
+"       ktrace [-adi] [-f trfile] [-t cnisuw] command");
 	exit(1);
 }
 
diff --git a/ktrace.tproj/ktrace.h b/ktrace.tproj/ktrace.h
index 75c4eab..9f6431a 100644
--- a/ktrace.tproj/ktrace.h
+++ b/ktrace.tproj/ktrace.h
@@ -1,26 +1,3 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
 /*-
  * Copyright (c) 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -57,7 +34,7 @@
  */
 
 #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \
-		  KTRFAC_GENIO | KTRFAC_PSIG)
+		  KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER)
 
 #define ALL_POINTS (DEF_POINTS | KTRFAC_CSW)
 
diff --git a/ktrace.tproj/subr.c b/ktrace.tproj/subr.c
index 08be415..90144d3 100644
--- a/ktrace.tproj/subr.c
+++ b/ktrace.tproj/subr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999, 2000-2001 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -23,7 +23,7 @@
  */
 /*-
  * Copyright (c) 1988, 1993
- *      The Regents of the University of California.  All rights reserved.
+ *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,8 +35,8 @@
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
- *      This product includes software developed by the University of
- *      California, Berkeley and its contributors.
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
@@ -54,6 +54,14 @@
  * SUCH DAMAGE.
  */
 
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)subr.c	8.1 (Berkeley) 6/6/93";
+#endif
+static const char rcsid[] =
+  "$FreeBSD: src/usr.bin/ktrace/subr.c,v 1.6 1999/08/28 01:02:34 peter Exp $";
+#endif /* not lint */
+
 #include <sys/param.h>
 #include <sys/file.h>
 #include <sys/user.h>
@@ -84,6 +92,9 @@ getpoints(s)
 		case 's':
 			facs |= KTRFAC_PSIG;
 			break;
+		case 'u':
+			facs |= KTRFAC_USER;
+			break;
 		case 'w':
 			facs |= KTRFAC_CSW;
 			break;
diff --git a/latency.tproj/Makefile b/latency.tproj/Makefile
index b647e65..9ff5ba4 100644
--- a/latency.tproj/Makefile
+++ b/latency.tproj/Makefile
@@ -23,7 +23,7 @@ MAKEFILE = tool.make
 NEXTSTEP_INSTALLDIR = /usr/bin
 WINDOWS_INSTALLDIR = /Library/Executables
 PDO_UNIX_INSTALLDIR = /bin
-LIBS = 
+LIBS = -lcurses
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
diff --git a/latency.tproj/latency.c b/latency.tproj/latency.c
index fc2cf35..f9bb800 100644
--- a/latency.tproj/latency.c
+++ b/latency.tproj/latency.c
@@ -24,7 +24,7 @@
 
 
 /* 
-   cc -I. -DKERNEL_PRIVATE -O -o latency latency.c
+   cc -I. -DKERNEL_PRIVATE -O -o latency latency.c -lncurses
 */
 
 #include <mach/mach.h>
@@ -42,7 +42,7 @@
 
 #include <libc.h>
 #include <termios.h>
-#include <bsd/curses.h>
+#include <curses.h>
 #include <sys/ioctl.h>
 
 #ifndef KERNEL_PRIVATE
@@ -124,6 +124,8 @@ char       pcstring[128];
 double   divisor;
 int      gotSIGWINCH = 0;
 int      trace_enabled = 0;
+struct host_basic_info  hi;
+
 
 #define SAMPLE_SIZE 300000
 
@@ -205,6 +207,9 @@ static kern_return_t	set_standard_policy(void);
 int decrementer_val = 0;     /* Value used to reset decrementer */
 int set_remove_flag = 1;     /* By default, remove trace buffer */
 
+kd_buf **last_decrementer_kd;   /* last DECR_TRAP per cpu */
+#define MAX_LOG_COUNT  30       /* limits the number of entries dumped in log_decrementer */
+
 int
 quit(s)
 char *s;
@@ -434,7 +439,7 @@ void sigintr()
         exit(1);
 }
 
-void sigquit()
+void leave()    /* exit under normal conditions -- signal handler */
 {
         set_enable(0);
 	set_pidexclude(getpid(), 0);
@@ -444,17 +449,6 @@ void sigquit()
         exit(1);
 }
 
-void sigterm()
-{
-        set_enable(0);
-	set_pidexclude(getpid(), 0);
-	set_rtcdec(0);
-	set_remove();
-	
-        exit(1);
-}
-
-
 void
 screen_update(FILE *fp)
 {
@@ -695,6 +689,10 @@ char *argv[];
 	double   nanosecs_to_sleep;
 	int      loop_cnt, sample_sc_now;
 	int      decrementer_usec = 0;
+        kern_return_t           ret;
+        int                     size;
+        int                     i, count;
+        host_name_port_t        host;
 	void     getdivisor();
 	void     sample_sc();
 	void     init_code_file();
@@ -792,6 +790,18 @@ char *argv[];
 	getdivisor();
 	decrementer_val = decrementer_usec * divisor;
 
+	/* get the cpu count for the DECR_TRAP array */
+        host = mach_host_self();
+	size = sizeof(hi)/sizeof(int);
+        ret = host_info(host, HOST_BASIC_INFO, (host_info_t)&hi, &size);
+        if (ret != KERN_SUCCESS) {
+            mach_error(argv[0], ret);
+            exit(EXIT_FAILURE);
+	}
+
+	if ((last_decrementer_kd = (kd_buf **)malloc(hi.avail_cpus * sizeof(kd_buf *))) == (kd_buf **)0)
+	        quit("can't allocate memory for decrementer tracing info\n");
+
 	nanosecs_to_sleep = (double)(num_of_usecs_to_sleep * 1000);
 	fdelay = nanosecs_to_sleep * (divisor /1000);
 	adelay = (uint64_t)fdelay;
@@ -805,13 +815,19 @@ char *argv[];
 	*/
 	set_rtcdec(decrementer_val);
 
-	initscr();
+	if (initscr() == (WINDOW *) 0)
+	  {
+	    printf("Unrecognized TERM type, try vt100\n");
+	    exit(1);
+	  }
+
 	clear();
 	refresh();
 	signal(SIGWINCH, sigwinch);
 	signal(SIGINT, sigintr);
-	signal(SIGQUIT, sigquit);
-	signal(SIGTERM, sigterm);
+	signal(SIGQUIT, leave);
+	signal(SIGTERM, leave);
+	signal(SIGHUP, leave);
 
 
 	if ((my_buffer = malloc(SAMPLE_SIZE * sizeof(kd_buf))) == (char *)0)
@@ -904,7 +920,11 @@ char *argv[];
 			}
 		}
 	        if (gotSIGWINCH) {
-		        initscr();
+		        /*
+			  No need to check for initscr error return.
+			  We won't get here if it fails on the first call.
+			*/
+		        endwin();
 			clear();
 			refresh();
 
@@ -1135,9 +1155,9 @@ char *find_code(type)
 
 void sample_sc(uint64_t start, uint64_t stop)
 {
-	kd_buf   *kd, *last_mach_sched, *last_decrementer_kd, *start_kd, *end_of_sample;
+	kd_buf   *kd, *last_mach_sched, *start_kd, *end_of_sample;
 	uint64_t now;
-	int count;
+	int count, i;
 	int first_entry = 1;
 	char   command[32];
 	double timestamp, last_timestamp, delta, start_bias;
@@ -1171,8 +1191,6 @@ void sample_sc(uint64_t start, uint64_t stop)
 	count = needed;
 
 	if (bufinfo.flags & KDBG_WRAPPED) {
-	        int i;
-
 	        for (i = 0; i < cur_max; i++) {
 			th_state[i].thread = 0;
 			th_state[i].type = -1;
@@ -1196,7 +1214,11 @@ void sample_sc(uint64_t start, uint64_t stop)
 		}
 	}
 	end_of_sample = &((kd_buf *)my_buffer)[count];
-	last_decrementer_kd = (kd_buf *)my_buffer;
+
+	/* Always reinitialize the DECR_TRAP array */
+	for (i=0; i < hi.avail_cpus; i++)
+	      last_decrementer_kd[i] = (kd_buf *)my_buffer;
+
 	last_mach_sched = (kd_buf *)0;
 
 	for (kd = (kd_buf *)my_buffer; kd < end_of_sample; kd++) {
@@ -1205,6 +1227,7 @@ void sample_sc(uint64_t start, uint64_t stop)
 		int len;
 		char *p;
 		long *sargptr;
+		kd_buf *cur_kd;
 		double i_latency;
 		struct th_info *ti;
 		char   command1[32];
@@ -1240,21 +1263,27 @@ void sample_sc(uint64_t start, uint64_t stop)
 			else if (debugid & DBG_FUNC_END)
 			        exit_syscall(log_fp, kd, thread, type, command, timestamp, delta, start_bias, 0);
 			else if (type == DECR_TRAP) {
+				cur_kd = kd;
 			        if (log_fp && i_thresh_hold && (int)i_latency > i_thresh_hold) {
-				        start_kd = last_decrementer_kd;
+				        start_kd = last_decrementer_kd[cpunum];
 				        kd = log_decrementer(start_kd, kd, end_of_sample, i_latency);
-
 					if (kd >= end_of_sample)
 					        break;
 				}
-				last_decrementer_kd = kd;
+				if ((kd->debugid & DBG_FUNC_MASK) == DECR_TRAP)
+				  {
+				    cpunum =  (kd->arg5 & KDBG_CPU_MASK) ? 1: 0;
+				    last_decrementer_kd[cpunum] = kd;
+				  }
+				else
+				  last_decrementer_kd[cpunum] = cur_kd;
 			}
 		        continue;
 		}
 		if (first_entry) {
 		        double latency;
-			char buf1[128];
-			char buf2[128];
+			char buf1[132];
+			char buf2[132];
 
 		        latency = (double)(stop - start) / divisor;
 			latency -= (double)num_of_usecs_to_sleep;
@@ -1323,7 +1352,7 @@ void sample_sc(uint64_t start, uint64_t stop)
 		    break;
 
 		case DECR_TRAP:
-		    last_decrementer_kd = kd;
+		    last_decrementer_kd[cpunum] = kd;
 
 		    if (i_thresh_hold && (int)i_latency > i_thresh_hold)
 		            p = "*";
@@ -1401,7 +1430,9 @@ void sample_sc(uint64_t start, uint64_t stop)
 			    ti->pathptr = (long *)0;
 			    ti->child_thread = 0;
 		    }
-		    if (!ti->pathptr) {
+		    while ( (kd < end_of_sample) && ((kd->debugid & DBG_FUNC_MASK) == VFS_LOOKUP))
+		      {
+			if (!ti->pathptr) {
 			    ti->arg1 = kd->arg1;
 			    memset(&ti->pathname[0], 0, (PATHLENGTH + 1));
 			    sargptr = (long *)&ti->pathname[0];
@@ -1411,7 +1442,7 @@ void sample_sc(uint64_t start, uint64_t stop)
 			    *sargptr++ = kd->arg4;
 			    ti->pathptr = sargptr;
 
-		    } else {
+			} else {
 		            sargptr = ti->pathptr;
 
 			    /*
@@ -1420,28 +1451,50 @@ void sample_sc(uint64_t start, uint64_t stop)
                                handle.
 			    */
 
-                            if ((long *)sargptr < (long *)&ti->pathname[PATHLENGTH])
+                            if ((long *)sargptr >= (long *)&ti->pathname[PATHLENGTH])
+			      {
+				kd++;
+				continue;
+			      }
+
+                            /*
+                              We need to detect consecutive vfslookup entries.
+                              So, if we get here and find a START entry,
+                              fake the pathptr so we can bypass all further
+                              vfslookup entries.
+			    */
+
+                            if (kd->debugid & DBG_FUNC_START)
+                              {
+                                (long *)ti->pathptr = (long *)&ti->pathname[PATHLENGTH];
+                              }
+			    else
 			      {
 				*sargptr++ = kd->arg1;
 				*sargptr++ = kd->arg2;
 				*sargptr++ = kd->arg3;
 				*sargptr++ = kd->arg4;
 				ti->pathptr = sargptr;
+			      }
+			}
+			kd++;
+		    }
+
+		    kd--;
 
 				/* print the tail end of the pathname */
-				len = strlen(ti->pathname);
-				if (len > 28)
-				  len -= 28;
-				else
-				  len = 0;
+		    len = strlen(ti->pathname);
+		    if (len > 42)
+		      len -= 42;
+		    else
+		      len = 0;
 			    
-				if (log_fp) {
-				  fprintf(log_fp, "%9.1f %8.1f\t\t%-28.28s %-28s    %-8x   %-8x  %d  %s\n",
-					  timestamp - start_bias, delta, "VFS_LOOKUP", 
-					  &ti->pathname[len], ti->arg1, thread, cpunum, command);
-				}
-			    }
+		    if (log_fp) {
+		      fprintf(log_fp, "%9.1f %8.1f\t\t%-14.14s %-42s    %-8x   %-8x  %d  %s\n",
+			      timestamp - start_bias, delta, "VFS_LOOKUP", 
+			      &ti->pathname[len], ti->arg1, thread, cpunum, command);
 		    }
+
 		    last_timestamp = timestamp;
 		    break;
 
@@ -1664,6 +1717,7 @@ check_for_thread_update(int thread, int type, kd_buf *kd)
 kd_buf *log_decrementer(kd_buf *kd_beg, kd_buf *kd_end, kd_buf *end_of_sample, double i_latency)
 {
         kd_buf *kd, *kd_start, *kd_stop;
+	int kd_count;     /* Limit the boundary of kd_start */
 	double timestamp, last_timestamp, delta, start_bias;
 	int thread, cpunum;
 	int debugid, type, clen;
@@ -1690,18 +1744,39 @@ kd_buf *log_decrementer(kd_buf *kd_beg, kd_buf *kd_end, kd_buf *end_of_sample, d
 	fprintf(log_fp, "RelTime(Us)  Delta              debugid                      arg1       arg2       arg3      arg4       thread   cpu   command\n\n");
 
 	thread = kd_beg->arg5 & KDBG_THREAD_MASK;
+	cpunum =  (kd_end->arg5 & KDBG_CPU_MASK) ? 1: 0;
 
-	for (kd_start = kd_beg - 1; (kd_start >= (kd_buf *)my_buffer) && (kd_start->arg5 & KDBG_THREAD_MASK) == thread; kd_start--) {
-	        if ((kd_start->debugid & DBG_FUNC_MASK) == DECR_TRAP)
+	for (kd_count = 0, kd_start = kd_beg - 1; (kd_start >= (kd_buf *)my_buffer); kd_start--, kd_count++) {
+	        if (kd_count == MAX_LOG_COUNT)
+		        break;
+
+		if((kd_start->arg5 & KDBG_CPU_MASK) != cpunum)
+		        continue;
+										     
+		if ((kd_start->debugid & DBG_FUNC_MASK) == DECR_TRAP)
+		        break;
+
+		if((kd_start->arg5 & KDBG_THREAD_MASK) != thread)
 		        break;
 	}
+
 	if (kd_start < (kd_buf *)my_buffer)
 	        kd_start = (kd_buf *)my_buffer;
 
-	for (kd_stop = kd_end + 1; kd_stop < end_of_sample && (kd_start->arg5 & KDBG_THREAD_MASK) == thread; kd_stop++) {
-	        if ((kd_stop->debugid & DBG_FUNC_MASK) == DECR_TRAP)
+	thread = kd_end->arg5 & KDBG_THREAD_MASK;
+
+	for (kd_stop = kd_end + 1; kd_stop < end_of_sample; kd_stop++) {
+										     
+		if ((kd_stop->debugid & DBG_FUNC_MASK) == DECR_TRAP)
+		        break;
+
+		if((kd_stop->arg5 & KDBG_CPU_MASK) != cpunum)
+		        continue;
+
+		if((kd_stop->arg5 & KDBG_THREAD_MASK) != thread)
 		        break;
 	}
+
 	if (kd_stop >= end_of_sample)
 	        kd_stop = end_of_sample - 1;
 
@@ -1825,7 +1900,10 @@ kd_buf *log_decrementer(kd_buf *kd_beg, kd_buf *kd_end, kd_buf *end_of_sample, d
 			    ti->pathptr = (long *)0;
 			    ti->child_thread = 0;
 		    }
-		    if (!ti->pathptr) {
+
+		    while ( (kd <= kd_stop) && (kd->debugid & DBG_FUNC_MASK) == VFS_LOOKUP)
+		      {
+			if (!ti->pathptr) {
 			    ti->arg1 = kd->arg1;
 			    memset(&ti->pathname[0], 0, (PATHLENGTH + 1));
 			    sargptr = (long *)&ti->pathname[0];
@@ -1835,7 +1913,7 @@ kd_buf *log_decrementer(kd_buf *kd_beg, kd_buf *kd_end, kd_buf *end_of_sample, d
 			    *sargptr++ = kd->arg4;
 			    ti->pathptr = sargptr;
 
-		    } else {
+			} else {
   		            sargptr = ti->pathptr;
 
 			    /*
@@ -1844,25 +1922,47 @@ kd_buf *log_decrementer(kd_buf *kd_beg, kd_buf *kd_end, kd_buf *end_of_sample, d
                                handle.
 			    */
 
-                            if ((long *)sargptr < (long *)&ti->pathname[PATHLENGTH])
+                            if ((long *)sargptr >= (long *)&ti->pathname[PATHLENGTH])
+			      {
+				kd++;
+				continue;
+			      }
+
+                            /*
+                              We need to detect consecutive vfslookup entries.
+                              So, if we get here and find a START entry,
+                              fake the pathptr so we can bypass all further
+                              vfslookup entries.
+			    */
+
+                            if (kd->debugid & DBG_FUNC_START)
+                              {
+                                (long *)ti->pathptr = (long *)&ti->pathname[PATHLENGTH];
+                              }
+			    else
 			      {
 				*sargptr++ = kd->arg1;
 				*sargptr++ = kd->arg2;
 				*sargptr++ = kd->arg3;
 				*sargptr++ = kd->arg4;
-
-				/* print the tail end of the pathname */
-				len = strlen(ti->pathname);
-				if (len > 28)
-				  len -= 28;
-				else
-				  len = 0;
-			    
-				fprintf(log_fp, "%9.1f %8.1f\t\t%-28.28s %-28s    %-8x   %-8x  %d  %s\n",
-					timestamp - start_bias, delta, "VFS_LOOKUP", 
-					&ti->pathname[len], ti->arg1, thread, cpunum, command);
+				ti->pathptr = sargptr;
 			      }
+			}
+			kd++;
 		    }
+
+		    kd--;
+		    /* print the tail end of the pathname */
+		    len = strlen(ti->pathname);
+		    if (len > 42)
+		      len -= 42;
+		    else
+		      len = 0;
+		    
+		    fprintf(log_fp, "%9.1f %8.1f\t\t%-14.14s %-42s    %-8x   %-8x  %d  %s\n",
+			    timestamp - start_bias, delta, "VFS_LOOKUP", 
+			    &ti->pathname[len], ti->arg1, thread, cpunum, command);
+
 		    last_timestamp = timestamp;
 		    break;
 
diff --git a/login.tproj/Makefile b/login.tproj/Makefile
index a148d4b..66d930a 100644
--- a/login.tproj/Makefile
+++ b/login.tproj/Makefile
@@ -25,7 +25,7 @@ MAKEFILE = tool.make
 NEXTSTEP_INSTALLDIR = /usr/bin
 WINDOWS_INSTALLDIR = /usr/bin
 PDO_UNIX_INSTALLDIR = /usr/bin
-LIBS = 
+LIBS = -lpam -lpam_misc
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
diff --git a/login.tproj/Makefile.postamble b/login.tproj/Makefile.postamble
index ec7f60d..039c5ed 100644
--- a/login.tproj/Makefile.postamble
+++ b/login.tproj/Makefile.postamble
@@ -1,6 +1,6 @@
 INSTALL_AS_USER =	root
 INSTALL_PERMISSIONS = 4555
-#CHFLAGS = /usr/bin/chflags
 
-#after_install::
-#	$(CHFLAGS) schg  $(DSTROOT)$(INSTALLDIR)/$(NAME)
+after_install:
+	mkdir -p "$(DSTROOT)/usr/share/man/man1"
+	install -c -m 644 login.1 "$(DSTROOT)/usr/share/man/man1/login.1"
diff --git a/login.tproj/Makefile.preamble b/login.tproj/Makefile.preamble
index b7b38d0..802d9eb 100644
--- a/login.tproj/Makefile.preamble
+++ b/login.tproj/Makefile.preamble
@@ -1,3 +1,5 @@
 CLEAN_ALL_SUBPROJECTS = YES
 OTHER_GENERATED_OFILES = $(VERS_OFILE)
+OTHER_CFLAGS = -DUSE_PAM -no-cpp-precomp
 
+AFTER_INSTALL = after_install
diff --git a/login.tproj/login.c b/login.tproj/login.c
index cbfd719..8b26084 100644
--- a/login.tproj/login.c
+++ b/login.tproj/login.c
@@ -70,6 +70,7 @@ static char copyright[] =
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/file.h>
+#include <sys/wait.h>
 
 #include <err.h>
 #include <errno.h>
@@ -86,6 +87,11 @@ static char copyright[] =
 #include <unistd.h>
 #include <utmp.h>
 
+#ifdef USE_PAM
+#include <pam/pam_appl.h>
+#include <pam/pam_misc.h>
+#endif
+
 #include "pathnames.h"
 
 void	 badlogin __P((char *));
@@ -121,7 +127,7 @@ int	authok;
 
 struct	passwd *pwd;
 int	failures;
-char	term[64], *envinit[1], *hostname, *username, *tty;
+char	term[64], *hostname, *username = NULL, *tty;
 
 int
 main(argc, argv)
@@ -133,11 +139,19 @@ main(argc, argv)
 	struct stat st;
 	struct timeval tp;
 	struct utmp utmp;
-	int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
+	int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin = 0, rval;
 	uid_t uid;
+	uid_t euid;
+	gid_t egid;
 	char *domain, *p, *salt, *ttyn;
 	char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
 	char localhost[MAXHOSTNAMELEN];
+#ifdef USE_PAM
+	pam_handle_t *pamh = NULL;
+	struct pam_conv conv = { misc_conv, NULL };
+	char **pmenv;
+	pid_t pid;
+#endif
 
 	(void)signal(SIGALRM, timedout);
 	(void)alarm(timeout);
@@ -158,6 +172,9 @@ main(argc, argv)
 		syslog(LOG_ERR, "couldn't get local hostname: %m");
 	else
 		domain = strchr(localhost, '.');
+	
+	euid = geteuid();
+	egid = getegid();
 
 	fflag = hflag = pflag = 0;
 	uid = getuid();
@@ -208,6 +225,91 @@ main(argc, argv)
 	else
 		tty = ttyn;
 
+#ifdef USE_PAM
+	rval = pam_start("login", username, &conv, &pamh);
+	if( rval != PAM_SUCCESS ) {
+		fprintf(stderr, "login: PAM Error:  %s\n", pam_strerror(pamh, rval));
+		exit(1);
+	}
+	rval = pam_set_item(pamh, PAM_TTY, tty);
+	if( rval != PAM_SUCCESS ) {
+		fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+		exit(1);
+	}
+
+	rval = pam_set_item(pamh, PAM_RHOST, hostname);
+	if( rval != PAM_SUCCESS ) {
+		fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+		exit(1);
+	}
+
+	rval = pam_set_item(pamh, PAM_USER_PROMPT, "login: ");
+	if( rval != PAM_SUCCESS ) {
+		fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+		exit(1);
+	}
+
+	if( !username )
+		getloginname();
+	pam_set_item(pamh, PAM_USER, username);
+	pwd = getpwnam(username);
+	if( (pwd != NULL) && (pwd->pw_uid == 0) )
+		rootlogin = 1;
+
+	if( (pwd != NULL) && fflag && ((uid == 0) || (uid == pwd->pw_uid)) ){
+		rval = 0;
+	} else {
+
+		rval = pam_authenticate(pamh, 0);
+		while( (cnt++ < 10) && ((rval == PAM_AUTH_ERR) ||
+				(rval == PAM_USER_UNKNOWN) ||
+				(rval == PAM_CRED_INSUFFICIENT) ||
+				(rval == PAM_AUTHINFO_UNAVAIL))) {
+			badlogin(username);
+			printf("Login incorrect\n");
+			rootlogin = 0;
+			getloginname();
+			pwd = getpwnam(username);
+			if( (pwd != NULL) && (pwd->pw_uid == 0) )
+				rootlogin = 1;
+			pam_set_item(pamh, PAM_USER, username);
+			rval = pam_authenticate(pamh, 0);
+		}
+
+		if( rval != PAM_SUCCESS ) {
+			pam_get_item(pamh, PAM_USER, (void *)&username);
+			badlogin(username);
+			printf("Login incorrect\n");
+			exit(1);
+		}
+
+		rval = pam_acct_mgmt(pamh, 0);
+		if( rval == PAM_NEW_AUTHTOK_REQD ) {
+			rval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+		}
+		if( rval != PAM_SUCCESS ) {
+			fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+			exit(1);
+		}
+	}
+
+	rval = pam_get_item(pamh, PAM_USER, (void *)&username);
+	if( (rval == PAM_SUCCESS) && username && *username) 
+		pwd = getpwnam(username);
+
+	rval = pam_open_session(pamh, 0);
+	if( rval != PAM_SUCCESS ) {
+		fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+		exit(1);
+	}
+
+	rval = pam_setcred(pamh, PAM_ESTABLISH_CRED);
+	if( rval != PAM_SUCCESS ) {
+		fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+		exit(1);
+	}
+
+#else /* USE_PAM */
 	for (cnt = 0;; ask = 1) {
 		if (ask) {
 			fflag = 0;
@@ -312,6 +414,7 @@ main(argc, argv)
 			sleep((u_int)((cnt - 3) * 5));
 		}
 	}
+#endif
 
 	/* committed to login -- turn off timeout */
 	(void)alarm((u_int)0);
@@ -322,6 +425,12 @@ main(argc, argv)
 	if (!rootlogin)
 		checknologin();
 
+	setegid(pwd->pw_gid);
+	seteuid(rootlogin ? 0 : pwd->pw_uid);
+
+      	/* First do a stat in case the homedir is automounted */
+
      	stat(pwd->pw_dir,&st);
+
 	if (chdir(pwd->pw_dir) < 0) {
 		(void)printf("No home directory %s!\n", pwd->pw_dir);
 		if (chdir("/"))
@@ -329,28 +438,11 @@ main(argc, argv)
 		pwd->pw_dir = "/";
 		(void)printf("Logging in with home = \"/\".\n");
 	}
+	seteuid(euid);
+	setegid(egid);
 
 	quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
 
-	if (pwd->pw_change || pwd->pw_expire)
-		(void)gettimeofday(&tp, (struct timezone *)NULL);
-	if (pwd->pw_change)
-		if (tp.tv_sec >= pwd->pw_change) {
-			(void)printf("Sorry -- your password has expired.\n");
-			sleepexit(1);
-		} else if (pwd->pw_change - tp.tv_sec <
-		    2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
-			(void)printf("Warning: your password expires on %s",
-			    ctime(&pwd->pw_change));
-	if (pwd->pw_expire)
-		if (tp.tv_sec >= pwd->pw_expire) {
-			(void)printf("Sorry -- your account has expired.\n");
-			sleepexit(1);
-		} else if (pwd->pw_expire - tp.tv_sec <
-		    2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
-			(void)printf("Warning: your account expires on %s",
-			    ctime(&pwd->pw_expire));
-
 	/* Nothing else left to fail -- really log in. */
 	memset((void *)&utmp, 0, sizeof(utmp));
 	(void)time(&utmp.ut_time);
@@ -373,8 +465,10 @@ main(argc, argv)
 		pwd->pw_shell = _PATH_BSHELL;
 
 	/* Destroy environment unless user has requested its preservation. */
-	if (!pflag)
-		environ = envinit;
+	if (!pflag) {
+		environ = malloc(sizeof(char *));
+		*environ = NULL;
+	}
 	(void)setenv("HOME", pwd->pw_dir, 1);
 	(void)setenv("SHELL", pwd->pw_shell, 1);
 	if (term[0] == '\0')
@@ -388,6 +482,24 @@ main(argc, argv)
 		(void)setenv("KRBTKFILE", krbtkfile_env, 1);
 #endif
 
+#ifdef USE_PAM
+	pmenv = pam_getenvlist(pamh);
+	for( cnt = 0; pmenv && pmenv[cnt]; cnt++ ) 
+		putenv(pmenv[cnt]);
+
+	pid = fork();
+	if ( pid < 0 ) {
+		err(1, "fork");
+	} else if( pid != 0 ) {
+		waitpid(pid, NULL, 0);
+		pam_setcred(pamh, PAM_DELETE_CRED);
+		rval = pam_close_session(pamh, 0);
+		pam_end(pamh,rval);
+		exit(0);
+	}
+
+#endif
+
 	if (tty[sizeof("tty")-1] == 'd')
 		syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
 
@@ -436,9 +548,9 @@ main(argc, argv)
 }
 
 #ifdef	KERBEROS
-#define	NBUFSIZ		(UT_NAMESIZE + 1 + 5)	/* .root suffix */
+#define	NBUFSIZ		(MAXLOGNAME + 1 + 5)	/* .root suffix */
 #else
-#define	NBUFSIZ		(UT_NAMESIZE + 1)
+#define	NBUFSIZ		(MAXLOGNAME + 1)
 #endif
 
 void
@@ -458,7 +570,7 @@ getloginname()
 			if (p < nbuf + (NBUFSIZ - 1))
 				*p++ = ch;
 		}
-		if (p > nbuf)
+		if (p > nbuf) {
 			if (nbuf[0] == '-')
 				(void)fprintf(stderr,
 				    "login names may not start with '-'.\n");
@@ -467,6 +579,7 @@ getloginname()
 				username = nbuf;
 				break;
 			}
+		}
 	}
 }
 
diff --git a/mach_init.tproj/Makefile b/mach_init.tproj/Makefile
index 706d04c..57431eb 100644
--- a/mach_init.tproj/Makefile
+++ b/mach_init.tproj/Makefile
@@ -1,5 +1,5 @@
 #
-# Generated by the NeXT Project Builder.
+# Generated by the Apple Project Builder.
 #
 # NOTE: Do NOT change this file -- Project Builder maintains it.
 #
@@ -12,12 +12,12 @@ NAME = mach_init
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Tool
 
-HFILES = bootstrap_internal.h error_log.h lists.h parser.h
+HFILES = bootstrap_internal.h error_log.h lists.h
 
-CFILES = bootstrap.c error_log.c lists.c parser.c rpc_services.c
+CFILES = bootstrap.c error_log.c lists.c rpc_services.c
 
-OTHERSRCS = Makefile.preamble Makefile initConf Notes testConfig\
-            testConfig2 bootstrap.defs testServer
+OTHERSRCS = Makefile.preamble Makefile bootstrap.defs mach_init.8\
+            Makefile.postamble
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
diff --git a/kmodstat.tproj/Makefile.postamble b/mach_init.tproj/Makefile.postamble
similarity index 95%
rename from kmodstat.tproj/Makefile.postamble
rename to mach_init.tproj/Makefile.postamble
index 5d1130d..9bd8df1 100644
--- a/kmodstat.tproj/Makefile.postamble
+++ b/mach_init.tproj/Makefile.postamble
@@ -80,7 +80,7 @@
         # User/group ownership 
 #INSTALL_AS_GROUP = wheel
         # (probably want to set both of these) 
-#INSTALL_PERMISSIONS =
+#INSTALL_PERMISSIONS = 4555
         # If set, 'install' chmod's executable to this
 
 
@@ -99,8 +99,6 @@
 # derived files should go.
 #
 
-after_install::
-	-mkdir -p ${DSTROOT}/usr/share/man/man8
-	-rm -f ${DSTROOT}/usr/share/man/man8/kmodstat.8
-	cp kmodstat.8 ${DSTROOT}/usr/share/man/man8/kmodstat.8
-	chmod og-w ${DSTROOT}/usr/share/man/man8/kmodstat.8
+install-man-page:
+	install -d $(DSTROOT)/usr/share/man/man8
+	install -c -m 444 mach_init.8 $(DSTROOT)/usr/share/man/man8/mach_init.8
diff --git a/mach_init.tproj/Makefile.preamble b/mach_init.tproj/Makefile.preamble
index ef0b259..02b60f4 100644
--- a/mach_init.tproj/Makefile.preamble
+++ b/mach_init.tproj/Makefile.preamble
@@ -1,4 +1,4 @@
 OTHER_GENERATED_OFILES = $(VERS_OFILE)
 BEFORE_BUILD += bootstrap.h
 OTHER_OFILES = bootstrapServer.o
-
+AFTER_INSTALL += install-man-page
diff --git a/mach_init.tproj/Notes b/mach_init.tproj/Notes
deleted file mode 100644
index 4c09847..0000000
--- a/mach_init.tproj/Notes
+++ /dev/null
@@ -1,71 +0,0 @@
-# gvdl@next 3 Aug 1995
-# Need to get the bootstrap .defs stuff working properly
-
-Format of /etc/bootstrap.conf
-
-[[restartable] (server|init) "SERVER_PATH ARGS"] [services { SERVICE_NAME
- [, SERVICE_NAME]* }]
-
-struct service {
-	struct service *next;
-	struct service *prev;
-	char *name;
-	port_t port;
-	struct server *server;
-	struct service *server_link;
-};
-
-struct server {
-	struct server *next;
-	struct server *prev;
-	boolean_t restartable;
-	boolean_t isEtcInit;
-	char **argv;
-	struct service *services;
-};
-
-Service entries create service-port pairs.  Lookup rpc's return send rights.  Checkin rpc's return all rights.  Checkin's can only be done from "privileged" bootstrap ports (see server, below).  Bootstrap is the default backup for service ports, if bootstrap receives the port back, it holds onto all rights (to give out on a later checkin), and marks the service inactive.  Lookup's on inactive services continue to return the service port.  Lookup's on unregistered services return PORT_NULL.
-
-Server entries initiate server tasks.  Server tasks receive a privileged bootstrap port that allows the server task to register new service-port pairs and perform checkin's.  Servers can obtain an unprivileged lookup/status-only port with an rpc; that port should be passed to untrusted progeny.  Servers are initiated in the order that they appear in bootstrap.conf.  Restartable servers are re-initiated if port destroyed or port deleted notification is received for all of the service ports declared by that server in bootstrap.conf.  On restart, a server may reobtain receive rights for service ports that were returned to bootstrap via the port backup mechanism.  New ports for are created for declared service ports without back-up when bootstrap receives a port deleted notification.  If bootstrap receives a port deleted notification for a registered, but undeclared service port, further lookups on that name return PORT_NULL.  Runtime registered ports are not associated with a server and are not involved in restart determination.  Rights for registered ports that specify bootstrap as backup will be held and may later be transfered to a new server instantiation via the checkin.  Should a new server instantiation re-register the service, the port and associated receive rights will be deallocated.
-
-There may only be a single init entry; it is a special server entry and provides a (hack) mechanism to allow /etc/init to be exec'ed as pid 1.  In the longer run, bootstrap should take over system shutdown/reconfig responsibilities and this won't be necessary.
-
-As a compatability hack, the initial version of bootstrap will initialize the ports inherited on task_create() via mach_ports_register().  Existing services utilizing service_checkin() will have to be modified to use bootstrap_checkin().
-
-Bootstrap rpc's:
-
-bootstrap_checkin(port_t priv_bootstrap_port, char *service_name,
-	port *service_port);
-	
-	Returns receive rights in service_port for service named by service_name.
-	FIXME: Success/Failure indication???
-	
-bootstrap_register(port_t priv_bootstrap_port, char *service_name,
-	port service_port);
-	
-	Registers service_name -- service_port pair.
-	FIXME: Success/Failure indication???
-	
-bootstrap_checkout(port_t priv_bootstrap_port, char *service_name);
-
-	Removes registration for service named by service_name.
-	Fails is service is currently active.
-	FIXME: Success/Failure indication???
-	
-bootstrap_lookup(port_t bootstrap_port, char *service_name, port_t service_port);
-
-	Returns service port for service named by service_name.
-	
-bootstrap_lookup_array(port_t bootstrap_port, name_array_t service_names, port_array_t service_ports, int service_count);
-
-	Returns service ports for all services named in service_names array.
-
-boostrap_status(port_t bootstrap_port, name_array_t service_names,
-	bool_array_t service_actives, int *service_count);
-	
-	Returns names and active status for all known services.
-	
-bootstrap_get_unpriv_port(port_t bootstrap_port, port_t *unpriv_bootstrap_port);
-
-	Returns the unprivileged bootstrap service port.
-
diff --git a/mach_init.tproj/PB.project b/mach_init.tproj/PB.project
index d937124..c099428 100644
--- a/mach_init.tproj/PB.project
+++ b/mach_init.tproj/PB.project
@@ -3,47 +3,44 @@
     FILESTABLE = {
         BUNDLES = (); 
         CLASSES = (); 
-        C_FILES = (); 
+        "C_FILES" = (); 
         FRAMEWORKS = (); 
         FRAMEWORKSEARCH = (); 
         HEADERSEARCH = (); 
-        H_FILES = (bootstrap_internal.h, error_log.h, lists.h, parser.h); 
-        M_FILES = (); 
-        OTHER_LIBS = (); 
-        OTHER_LINKED = (bootstrap.c, error_log.c, lists.c, parser.c, rpc_services.c); 
-        OTHER_SOURCES = (
-            Makefile.preamble, 
+        "H_FILES" = ("bootstrap_internal.h", "error_log.h", "lists.h"); 
+        "M_FILES" = (); 
+        "OTHER_LIBS" = (); 
+        "OTHER_LINKED" = ("bootstrap.c", "error_log.c", "lists.c", "rpc_services.c"); 
+        "OTHER_SOURCES" = (
+            "Makefile.preamble", 
             Makefile, 
-            initConf, 
-            Notes, 
-            testConfig, 
-            testConfig2, 
-            bootstrap.defs, 
-            testServer
+            "bootstrap.defs", 
+            "mach_init.8", 
+            "Makefile.postamble"
         ); 
         SUBPROJECTS = (); 
         TOOLS = (); 
     }; 
     LANGUAGE = English; 
-    LOCALIZABLE_FILES = {}; 
-    NEXTSTEP_BUILDDIR = "/tmp/$(USER)/BUILD"; 
-    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
-    NEXTSTEP_COMPILEROPTIONS = "-DMACH_USER_API"; 
-    NEXTSTEP_INSTALLDIR = /sbin; 
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
-    NEXTSTEP_MAINNIB = mach_init; 
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
-    PDO_UNIX_COMPILEROPTIONS = "-DMACH_USER_API"; 
-    PDO_UNIX_INSTALLDIR = /sbin; 
-    PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac"; 
-    PDO_UNIX_MAINNIB = mach_init; 
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
-    PROJECTNAME = mach_init; 
+    "LOCALIZABLE_FILES" = {}; 
+    "NEXTSTEP_BUILDDIR" = "/tmp/$(USER)/BUILD"; 
+    "NEXTSTEP_BUILDTOOL" = "/bin/gnumake"; 
+    "NEXTSTEP_COMPILEROPTIONS" = "-DMACH_USER_API"; 
+    "NEXTSTEP_INSTALLDIR" = "/sbin"; 
+    "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac"; 
+    "NEXTSTEP_MAINNIB" = "mach_init"; 
+    "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc"; 
+    "PDO_UNIX_COMPILEROPTIONS" = "-DMACH_USER_API"; 
+    "PDO_UNIX_INSTALLDIR" = "/sbin"; 
+    "PDO_UNIX_JAVA_COMPILER" = "$(NEXTDEV_BIN)/javac"; 
+    "PDO_UNIX_MAINNIB" = "mach_init"; 
+    "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = "mach_init"; 
     PROJECTTYPE = Tool; 
-    PROJECTVERSION = 2.8; 
-    WINDOWS_COMPILEROPTIONS = "-DMACH_USER_API"; 
-    WINDOWS_INSTALLDIR = /sbin; 
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
-    WINDOWS_MAINNIB = mach_init; 
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+    PROJECTVERSION = "2.8"; 
+    "WINDOWS_COMPILEROPTIONS" = "-DMACH_USER_API"; 
+    "WINDOWS_INSTALLDIR" = "/sbin"; 
+    "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe"; 
+    "WINDOWS_MAINNIB" = "mach_init"; 
+    "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc"; 
 }
diff --git a/mach_init.tproj/bootstrap.c b/mach_init.tproj/bootstrap.c
index f55d191..03c394d 100644
--- a/mach_init.tproj/bootstrap.c
+++ b/mach_init.tproj/bootstrap.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -45,17 +45,19 @@
 #include <mach/exception.h>
 
 #import <sys/ioctl.h>
+#import <sys/types.h>
+#import <sys/wait.h>
+#import <pthread.h>
 #import	<string.h>
 #import	<ctype.h>
 #import	<stdio.h>
 #import <libc.h>
 
-#include "bootstrap.h"
+#import "bootstrap.h"
 
 #import "bootstrap_internal.h"
 #import "lists.h"
 #import "error_log.h"
-#import "parser.h"
 
 /* Mig should produce a declaration for this,  but doesn't */
 extern boolean_t bootstrap_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
@@ -65,41 +67,19 @@ extern boolean_t bootstrap_server(mach_msg_header_t *InHeadP, mach_msg_header_t
  */
 const char *program_name;	/* our name for error messages */
 
-#ifndef CONF_FILE
-#define	CONF_FILE	"/etc/bootstrap.conf"	/* default config file */
-#endif CONF_FILE
-
-const char *conf_file = CONF_FILE;
-
-const unsigned BOOTSTRAP_REPLY_TIMEOUT = 10 * 1000; // 10 sec reply timeout
-#ifdef notyet
-port_all_t backup_port;
-#endif /* notyet */
-/*
- * Last resort configuration
- *
- * If we can't find a /etc/bootstrap.conf, we use this configuration.
- * The services defined here are compatable with the old mach port stuff,
- * and of course, the names for these services should not be modified without
- * modifying mach_init in libc.
- */
-const char *default_conf =
-	"init \"/sbin/init\";"
-	"services NetMessage;";
+#ifndef INIT_PATH
+#define INIT_PATH	"/sbin/init"			/* default init path */
+#endif  INIT_PATH
 	
+uid_t inherited_uid;
 mach_port_t inherited_bootstrap_port = MACH_PORT_NULL;
 boolean_t forward_ok = FALSE;
+boolean_t shutdown_in_progress = FALSE;
 boolean_t debugging = FALSE;
 boolean_t register_self = FALSE;
-int init_priority = BASEPRI_USER;
-char *register_name = NULL;
-mach_port_t	bootstrap_master_device_port;	/* local name */
-mach_port_t	bootstrap_master_host_port;	/* local name */
-mach_port_t	bootstrap_notification_port;	/* local name */
-mach_port_t	security_port;
-mach_port_t	root_ledger_wired;
-mach_port_t	root_ledger_paged;
-task_port_t	bootstrap_self;
+boolean_t force_fork = FALSE;
+const char *register_name;
+task_t	bootstrap_self;
 
 #ifndef ASSERT
 #define ASSERT(p)
@@ -115,15 +95,20 @@ task_port_t	bootstrap_self;
 /*
  * Private declarations
  */	
-static void add_init_arg(const char *arg);
 static void wait_for_go(mach_port_t init_notify_port);
 static void init_ports(void);
 static void start_server(server_t *serverp);
-static void unblock_init(task_port_t task, mach_port_t newBootstrap);
+static void unblock_init(mach_port_t init_notify_port, mach_port_t newBootstrap);
 static void exec_server(server_t *serverp);
 static char **argvize(const char *string);
+static void *demand_loop(void *arg);
 static void server_loop(void);
-static void msg_destroy(mach_msg_header_t *m);
+extern kern_return_t bootstrap_register
+(
+	mach_port_t bootstrap_port,
+	name_t service_name,
+	mach_port_t service_port
+);
 
 /*
  * Private ports we hold receive rights for.  We also hold receive rights
@@ -131,35 +116,134 @@ static void msg_destroy(mach_msg_header_t *m);
  * structs.
  */
 mach_port_t bootstrap_port_set;
+mach_port_t demand_port_set;
+pthread_t	demand_thread;
+
 mach_port_t notify_port;
+mach_port_t backup_port;
 
-static int init_pid;
-static int running_servers;
-static char init_args[BOOTSTRAP_MAX_CMD_LEN];
+static void
+notify_server_loop(mach_port_name_t about)
+{
+	mach_port_destroyed_notification_t not;
+	mach_msg_return_t nresult;
+
+	not.not_header.msgh_id = DEMAND_REQUEST;
+	not.not_header.msgh_remote_port = backup_port;
+	not.not_header.msgh_local_port = MACH_PORT_NULL;
+	not.not_header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
+	not.not_header.msgh_size = sizeof(not) - sizeof(not.trailer);
+	not.not_body.msgh_descriptor_count = 1;
+	not.not_port.type = MACH_MSG_PORT_DESCRIPTOR;
+	not.not_port.disposition = MACH_MSG_TYPE_PORT_NAME;
+	not.not_port.name = about;
+	nresult = mach_msg_send(&not.not_header);
+	if (nresult != MACH_MSG_SUCCESS) {
+		kern_error(nresult, "notify_server: mach_msg_send()");
+	}
+}
 
 void _myExit(int arg)
 {
     exit(arg);
 }
 
-/* It was a bozo who made main return a value!  Civil disobedience, here. */
-void
-main(int argc, const char * const argv[])
+void toggle_debug(int signal)
+{
+	debugging = (debugging) ? FALSE : TRUE;
+}
+
+void start_shutdown(int signal)
+{
+	debug("received SIGTERM");
+	shutdown_in_progress = TRUE;
+	notify_server_loop(MACH_PORT_DEAD);
+}
+
+int
+main(int argc, char * argv[])
 {
 	const char *argp;
 	char c;
-	server_t *init_serverp;
 	server_t *serverp;
-	mach_port_t init_notify_port;
 	kern_return_t result;
+	mach_port_t init_notify_port;
+	pthread_attr_t  attr;
+	sigset_t mask;
 	int pid;
-	int force_fork = FALSE;
-	mach_port_t prev_port;
-#if defined(__APPLE__)
-        extern void exit(int);
-	
-	/* signal (SIGUSR2, _myExit); */
-#endif
+
+	/*
+	 * If we are pid one, we have to exec init.  Before doing so, we'll
+	 * fork a child, and that will become the true mach_init.  But we have
+	 * to be very careful about ports.  They aren't inherited across fork,
+	 * so we have to avoid storing port names in memory before the fork that
+	 * might not be valid after.
+	 */
+	pid = getpid();
+	if (pid == 1)
+	{
+		close(0);
+		freopen("/dev/console", "r", stdin);
+		setbuf(stdin, NULL);
+		close(1);
+		freopen("/dev/console", "w", stdout);
+		setbuf(stdout, NULL);
+		close(2);
+		freopen("/dev/console", "w", stderr);
+		setbuf(stderr, NULL);
+
+		result = mach_port_allocate(
+						mach_task_self(),
+						MACH_PORT_RIGHT_RECEIVE,
+						&init_notify_port);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_allocate");
+
+		result = mach_port_insert_right(
+						mach_task_self(),
+						init_notify_port,
+						init_notify_port,
+						MACH_MSG_TYPE_MAKE_SEND);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_insert_right");
+
+		result = task_set_bootstrap_port(
+						mach_task_self(),
+						init_notify_port);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "task_set_bootstrap_port");
+
+		pid = fork();
+
+		if (pid < 0)
+			unix_fatal("fork");
+
+		else if (pid != 0) {  /* PARENT - will become init when ready */
+			int fd;
+
+			/*
+			 * Wait for mach_init ot give us a real bootstrap port
+			 */
+			wait_for_go(init_notify_port);
+			info("Execing init");
+
+			close(0);
+			close(1);
+			close(2);
+			fd = open("/dev/tty", O_RDONLY);
+			if (fd >= 0) {
+				ioctl(fd, TIOCNOTTY, 0);
+				close(fd);
+			}
+			
+			/* pass our arguments on to init */
+			argv[0] = INIT_PATH;
+			execv(argv[0], argv);
+			exit(1);  /* will likely trigger a panic */
+
+		}
+	} else
+		init_notify_port = MACH_PORT_NULL;
 
 	/* Initialize error handling */
  	program_name = rindex(*argv, '/');
@@ -169,35 +253,8 @@ main(int argc, const char * const argv[])
 		program_name = *argv;
  	argv++; argc--;
 
-	init_pid = getpid();
-	init_errlog(init_pid == 1);
-
-	/*
-	 * Get master host and device ports
-	 */
-#if 0
-	result = bootstrap_ports(bootstrap_port,
-			     &bootstrap_master_host_port,
-			     &bootstrap_master_device_port,
-			     &root_ledger_wired,
-			     &root_ledger_paged,
-			     &security_port);
-	if (result != KERN_SUCCESS) {
-	printf("bootstrap_ports failed \n");
-		kern_error(result, "bootstrap_ports");
-	}
-#endif /* 0 */
-	/*
-	 *	This task will become the bootstrap task.
-	 */
-	bootstrap_self = mach_task_self();
-
-	/* Initialize globals */
-	init_lists();
-
 	/* Parse command line args */
 	while (argc > 0 && **argv == '-') {
-		boolean_t init_arg = FALSE;
 		argp = *argv++ + 1; argc--;
 		while (*argp) {
 			switch (c = *argp++) {
@@ -210,15 +267,6 @@ main(int argc, const char * const argv[])
 			case 'F':
 				force_fork = TRUE;
 				break;
-			case 'f':
-				if (argc > 0) {
-					conf_file = *argv++; argc--;
-				} else
-					fatal("-f requires config file name");
-				break;
-			case '-':
-				init_arg = TRUE;
-				break;
 			case 'r':
 				register_self = forward_ok = TRUE;
 				if (argc > 0) {
@@ -226,232 +274,265 @@ main(int argc, const char * const argv[])
 				} else
 					fatal("-r requires name");
 				break;
+			case '-':
 			default:
-				init_arg = TRUE;
 				break;
 			}
 		}
-		if (init_arg) {
-			add_init_arg(argv[-1]);
-			goto copyargs;
-		}
-	}
-    copyargs:
-	while (argc != 0) {
-		argc--;
-		add_init_arg(*argv++);
 	}
 
-	log("Started");
-
-	/* Parse the config file */
-	init_config();
-
-	/* set_default_policy(bootstrap_master_host_port); */
-
 	/*
-	 * If we have to run init as pid 1, use notify port to
-	 * synchronize init and bootstrap
+	 * If we must fork, do it now before we get Mach ports in use
 	 */
-	if ((init_serverp = find_init_server()) != NULL) {
-		if (init_pid != 1 && ! debugging)
-			fatal("Can't start init server if not pid 1");
-            result = mach_port_allocate(bootstrap_self, MACH_PORT_RIGHT_RECEIVE,
-                                    &init_notify_port);
-            if (result != KERN_SUCCESS)
-                    kern_fatal(result, "mach_port_allocate");
-            result = mach_port_insert_right(mach_task_self(), init_notify_port, init_notify_port, MACH_MSG_TYPE_MAKE_SEND);
-            if (result != KERN_SUCCESS)
-                kern_fatal(result, "mach_port_insert_right");
-            task_set_bootstrap_port(bootstrap_self, init_notify_port);
-            if (result != KERN_SUCCESS)
-                kern_fatal(result, "task_set_bootstrap_port");
-	    /*
-	     *  XXX restart the service if it dies?
-	     */
-                result = mach_port_request_notification(mach_task_self(),
-						mach_task_self(),
-						MACH_NOTIFY_DEAD_NAME,
-						0,
-						init_notify_port,
-						MACH_MSG_TYPE_MAKE_SEND_ONCE,
-						&prev_port);
-	    if (result != KERN_SUCCESS)
-			kern_fatal(result, "mach_port_request_notification");
-		debug("Set port %d for parent proc notify port",
-		      init_notify_port);
-                } else if (init_args[0] != '\0')
-		fatal("Extraneous command line arguments");
-	
-	/* Fork if either not debugging or running /etc/init */
-	if (force_fork || !debugging || init_serverp != NULL) {
+	if (force_fork) {
 		pid = fork();
 		if (pid < 0)
 			unix_fatal("fork");
-	} else
-		pid = 0;
+		else if (pid != 0) /* PARENT: just exit */
+			exit(0);
+	}
+
+	/* block all but SIGHUP and SIGTERM and mark us as an init process */
+	setsid();
+	sigfillset(&mask);
+	sigdelset(&mask, SIGHUP);
+	signal(SIGHUP, toggle_debug);
+	sigdelset(&mask, SIGTERM);
+	signal(SIGTERM, start_shutdown);
+	(void) sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+
+	init_errlog(pid == 0); /* are we a daemon? */
+	init_lists();
+
+	/*
+	 *	This task will become the bootstrap task, so go ahead and
+	 *	initialize the ports now.
+	 */
+	bootstrap_self = mach_task_self();
+	inherited_uid = getuid();
+	init_ports();
 	
-	/* Bootstrap service runs in child (if there is one) */
-	if (pid == 0) {	/* CHILD */
-		/*
-		 * If we're initiated by pid 1, we shouldn't get ever get 
-		 * killed; designate ourselves as an "init process".
-		 *
-		 * This should go away with new signal stuff!
-		 */
-            if (init_pid == 1)
-			init_process();
+	log("Started with uid=%d%s%s%s",
+		inherited_uid,
+		(register_self) ? " registered-as=" : "",
+		(register_self) ? register_name : "",
+		(debugging) ? " in debug-mode" : "");
 
-            /* Create declared service ports, our service port, etc */	
-		init_ports();
 
-		/* Kick off all server processes */
-		for (  serverp = FIRST(servers)
-		     ; !IS_END(serverp, servers)
-		     ; serverp = NEXT(serverp))
-			start_server(serverp);
-		
-		/*
-		 * If our priority's to be changed, set it up here.
-		 */
-#ifdef notyet
-		if (init_priority >= 0) {
-			result = task_priority(mach_task_self(), init_priority,
-				TRUE);
+	/*
+	 * If we are supposed to coordinate with init, we have to
+	 * get that port again, because we only have a (probably wrong)
+	 * name in memory, not a proper right.
+ 	 */
+	if (init_notify_port != MACH_PORT_NULL) {
+		result = task_get_bootstrap_port(
+						 	bootstrap_self,
+						 	&init_notify_port);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "task_get_bootstrap_port");
+
+		unblock_init(init_notify_port, bootstraps.bootstrap_port);
+
+		result = task_set_bootstrap_port(
+							bootstrap_self,
+							MACH_PORT_NULL);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "task_set_bootstrap_port");
+
+		result = mach_port_deallocate(
+							bootstrap_self,
+							init_notify_port);  
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_deallocate");
+
+		forward_ok = FALSE;
+		inherited_bootstrap_port = MACH_PORT_NULL;
+
+	} else {
+
+		/* get inherited bootstrap port */
+		result = task_get_bootstrap_port(
+							bootstrap_self,
+							&inherited_bootstrap_port);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "task_get_bootstrap_port");
+
+		/* We set this explicitly as we start each child */
+		task_set_bootstrap_port(bootstrap_self, MACH_PORT_NULL);
+		if (inherited_bootstrap_port == MACH_PORT_NULL)
+			forward_ok = FALSE;
+
+		/* register "self" port with anscestor */		
+		if (register_self && forward_ok) {
+			result = bootstrap_register(
+							inherited_bootstrap_port,
+							(char *)register_name,
+							bootstraps.bootstrap_port);
 			if (result != KERN_SUCCESS)
-				kern_error(result, "task_priority %d",
-					init_priority);
+				kern_fatal(result, "register self");
 		}
-#endif /* notyet */
-		/* Process bootstrap service requests */
-		server_loop();	/* Should never return */
-                exit(1);
 	}
-	
-	/* PARENT */
-	if (init_serverp != NULL) {
-		int i;
 
-		strncat(init_serverp->cmd,
-			init_args,
-			sizeof(init_serverp->cmd));
-		/*
-		 * Wait, then either exec /etc/init or exit
-		 * (which panics the system)
-		 */
-		for (i = 3; i; i--)
-			close(i);
-		wait_for_go(init_notify_port);
-                exec_server(init_serverp);
+
+	/* Kick off all continuously running server processes */
+	for (  serverp = FIRST(servers)
+		; !IS_END(serverp, servers)
+		; serverp = NEXT(serverp))
+		if (serverp->servertype != DEMAND)
+			start_server(serverp);
+
+	pthread_attr_init (&attr);
+	pthread_attr_setdetachstate ( &attr, PTHREAD_CREATE_DETACHED );
+	result = pthread_create(
+						&demand_thread,
+						&attr,
+						demand_loop,
+						NULL);
+	if (result) {
+		unix_error("pthread_create()");
 		exit(1);
 	}
-	exit(0);
-}
 
-static void
-add_init_arg(const char *arg)
-{
-	strncat(init_args, " ", sizeof(init_args));
-	strncat(init_args, arg, sizeof(init_args));
+	/* Process bootstrap service requests */
+	server_loop();	/* Should never return */
+	exit(1);
 }
 
 static void
 wait_for_go(mach_port_t init_notify_port)
 {
-        struct {
+	struct {
             mach_msg_header_t hdr;
             mach_msg_trailer_t trailer;
-        } init_go_msg;
+	} init_go_msg;
 	kern_return_t result;
 
-        /*
+	/*
 	 * For now, we just blindly wait until we receive a message or
 	 * timeout.  We don't expect any notifications, and if we get one,
 	 * it probably means something dire has happened; so we might as
 	 * well give a shot at letting init run.
 	 */	
-        result = mach_msg(&init_go_msg.hdr, MACH_RCV_MSG, 0, sizeof(init_go_msg), init_notify_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-        if (result != KERN_SUCCESS) {
-            kern_error(result, "mach_msg(receive) failed in wait_for_go");
-        }
-        result = task_set_bootstrap_port(mach_task_self(), init_go_msg.hdr.msgh_remote_port);
-        if (result != KERN_SUCCESS) {
-            kern_error(result, "task_get_bootstrap_port()");
-        }
+	result = mach_msg(
+						&init_go_msg.hdr, MACH_RCV_MSG,
+						0, sizeof(init_go_msg), init_notify_port,
+						MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+	if (result != KERN_SUCCESS) {
+		kern_error(result, "mach_msg(receive) failed in wait_for_go");
+	}
+	result = task_set_bootstrap_port(
+						mach_task_self(),
+						init_go_msg.hdr.msgh_remote_port);
+	if (result != KERN_SUCCESS) {
+		kern_error(result, "task_get_bootstrap_port()");
+	}
 }
 
+
+static void
+unblock_init(mach_port_t init_notify_port, 
+			 mach_port_t newBootstrap)
+{
+	mach_msg_header_t init_go_msg;
+	kern_return_t result;
+
+	/*
+	 * Proc 1 is blocked in a msg_receive on its notify port, this lets
+	 * it continue, and we hand off its new bootstrap port
+	 */
+	init_go_msg.msgh_remote_port = init_notify_port;
+	init_go_msg.msgh_local_port = newBootstrap;
+        init_go_msg.msgh_bits = MACH_MSGH_BITS(
+								MACH_MSG_TYPE_COPY_SEND,
+								MACH_MSG_TYPE_MAKE_SEND);
+	init_go_msg.msgh_size = sizeof(init_go_msg);
+        result = mach_msg_send(&init_go_msg);
+	if (result != KERN_SUCCESS)
+		kern_fatal(result, "unblock_init mach_msg_send() failed");
+	debug("sent go message");
+}
+
+
 static void
 init_ports(void)
 {
 	kern_return_t result;
 	service_t *servicep;
-	mach_port_name_t previous;
-	mach_port_t pport;
 
 	/*
 	 *	This task will become the bootstrap task.
 	 */
-	bootstrap_self = mach_task_self();
-
-	/* get inherited bootstrap port */
-	result = task_get_bootstrap_port(bootstrap_self,
-					 &inherited_bootstrap_port);
+	/* Create port set that server loop listens to */
+	result = mach_port_allocate(
+						bootstrap_self,
+						MACH_PORT_RIGHT_PORT_SET,
+						&bootstrap_port_set);
 	if (result != KERN_SUCCESS)
-		kern_fatal(result, "task_get_bootstrap_port");
+		kern_fatal(result, "port_set_allocate");
 
-	/* We set this explicitly as we start each child */
-	task_set_bootstrap_port(bootstrap_self, MACH_PORT_NULL);
-	if (inherited_bootstrap_port == MACH_PORT_NULL)
-		forward_ok = FALSE;
-	
-	/* Create port set that server loop listens to */
-	result = mach_port_allocate(bootstrap_self, MACH_PORT_RIGHT_PORT_SET,
-				&bootstrap_port_set);
+	/* Create demand port set that second thread listens to */
+	result = mach_port_allocate(
+						bootstrap_self,
+						MACH_PORT_RIGHT_PORT_SET,
+						&demand_port_set);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "port_set_allocate");
+
 	/* Create notify port and add to server port set */
-	result = mach_port_allocate(bootstrap_self, MACH_PORT_RIGHT_RECEIVE,
-				&notify_port);
+	result = mach_port_allocate(
+						bootstrap_self,
+						MACH_PORT_RIGHT_RECEIVE,
+						&notify_port);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "mach_port_allocate");
 
-	result = mach_port_request_notification(bootstrap_self,
+	result = mach_port_move_member(
 						bootstrap_self,
-						MACH_NOTIFY_DEAD_NAME,
-						0,
 						notify_port,
-						MACH_MSG_TYPE_MAKE_SEND_ONCE,
-						&pport);
+						bootstrap_port_set);
+	if (result != KERN_SUCCESS)
+		kern_fatal(result, "mach_port_move_member");
+	
+	/* Create backup port and add to server port set */
+	result = mach_port_allocate(
+						bootstrap_self,
+						MACH_PORT_RIGHT_RECEIVE,
+						&backup_port);
 	if (result != KERN_SUCCESS)
-		kern_fatal(result, "task_set_notify_port");
+		kern_fatal(result, "mach_port_allocate");
 
-	result = mach_port_move_member(bootstrap_self,
-				   notify_port,
-				   bootstrap_port_set);
+	result = mach_port_move_member(
+						bootstrap_self,
+						backup_port,
+						bootstrap_port_set);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "mach_port_move_member");
 	
 	/* Create "self" port and add to server port set */
-	result = mach_port_allocate(bootstrap_self, MACH_PORT_RIGHT_RECEIVE,
-				&bootstraps.bootstrap_port);
+	result = mach_port_allocate(
+						bootstrap_self,
+						MACH_PORT_RIGHT_RECEIVE,
+						&bootstraps.bootstrap_port);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "mach_port_allocate");
-        result = mach_port_insert_right(mach_task_self(), bootstraps.bootstrap_port, bootstraps.bootstrap_port, MACH_MSG_TYPE_MAKE_SEND);
-        if (result != KERN_SUCCESS)
-            kern_fatal(result, "mach_port_insert_right");
-	result = mach_port_move_member(bootstrap_self,
-				   bootstraps.bootstrap_port,
-				   bootstrap_port_set);
+	result = mach_port_insert_right(
+						bootstrap_self,
+						bootstraps.bootstrap_port,
+						bootstraps.bootstrap_port,
+						MACH_MSG_TYPE_MAKE_SEND);
+	if (result != KERN_SUCCESS)
+		kern_fatal(result, "mach_port_insert_right");
+
+	/* keep the root bootstrap port "active" */
+	bootstraps.requestor_port = bootstraps.bootstrap_port;
+
+	result = mach_port_move_member(
+						bootstrap_self,
+						bootstraps.bootstrap_port,
+						bootstrap_port_set);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "mach_port_move_member");
-#ifdef notyet 
-	/* register "self" port with anscestor */		
-	if (register_self && forward_ok) {
-		result = bootstrap_register(inherited_bootstrap_port, register_name, bootstraps.bootstrap_port);
-		if (result != KERN_SUCCESS)
-			kern_fatal(result, "register self");
-	}
-#endif /* notyet*/
+
 	/*
 	 * Allocate service ports for declared services.
 	 */
@@ -461,32 +542,45 @@ init_ports(void)
 	{
 	 	switch (servicep->servicetype) {
 		case DECLARED:
-			result = mach_port_allocate(bootstrap_self, MACH_PORT_RIGHT_RECEIVE,
-				&(servicep->port));
+			result = mach_port_allocate(
+							bootstrap_self,
+							MACH_PORT_RIGHT_RECEIVE,
+							&(servicep->port));
 			if (result != KERN_SUCCESS)
 				kern_fatal(result, "mach_port_allocate");
-			result = mach_port_insert_right(bootstrap_self, servicep->port, servicep->port, MACH_MSG_TYPE_MAKE_SEND);
+
+			result = mach_port_insert_right(
+							bootstrap_self,
+							servicep->port,
+							servicep->port,
+							MACH_MSG_TYPE_MAKE_SEND);
 			if (result != KERN_SUCCESS)
 				kern_fatal(result, "mach_port_insert_right");
-			debug("Declared port %d for service %s",
+			info("Declared port %x for service %s",
 			      servicep->port,
 			      servicep->name);
-#ifdef notyet
-			result = port_set_backup(task_self(),
-						 servicep->port,
-						 backup_port,
-						 &previous);
-			if (result != KERN_SUCCESS)
-				kern_fatal(result, "port_set_backup");
-#endif /* notyet */
+
+			if (servicep->server != NULL_SERVER &&
+				servicep->server->servertype == DEMAND) {
+				result = mach_port_move_member(
+								bootstrap_self,
+								servicep->port,
+								demand_port_set);
+				if (result != KERN_SUCCESS)
+					kern_fatal(result, "mach_port_move_member");
+			}
 			break;
+
 		case SELF:
 			servicep->port = bootstraps.bootstrap_port;
-			servicep->server = new_server(MACHINIT,
-				program_name, init_priority);
-			info("Set port %d for self port",
+			servicep->server = new_server(&bootstraps,
+							program_name,
+							inherited_uid,
+							MACHINIT);
+			info("Set port %x for self port",
 			      bootstraps.bootstrap_port);
 			break;
+
 		case REGISTERED:
 			fatal("Can't allocate REGISTERED port!?!");
 			break;
@@ -494,152 +588,278 @@ init_ports(void)
 	}
 }
 
+boolean_t
+active_bootstrap(bootstrap_info_t *bootstrap)
+{
+	return (bootstrap->requestor_port != MACH_PORT_NULL);
+}
+
+boolean_t
+useless_server(server_t *serverp)
+{
+	return (	!active_bootstrap(serverp->bootstrap) || 
+				!lookup_service_by_server(serverp) ||
+				!serverp->activity);
+}
+
+boolean_t
+active_server(server_t *serverp)
+{
+	return (
+#ifdef DELAYED_BOOTSTRAP_DESTROY
+			serverp->port ||
+#else
+			(serverp->port && serverp->pid == NO_PID) ||
+#endif
+			serverp->task_port || serverp->active_services);
+}
+
 static void
-start_server(server_t *serverp)
+reap_server(server_t *serverp)
+{
+	kern_return_t result;
+	pid_t	presult;
+	int		wstatus;
+
+	/*
+	 * Reap our children.
+	 */
+	presult = waitpid(serverp->pid, &wstatus, WNOHANG);
+	if (presult != serverp->pid) {
+		unix_error("waitpid: cmd = %s", serverp->cmd);
+	} else if (wstatus) {
+		log("Server %x in bootstrap %x uid %d: \"%s\": %s %d [pid %d]",
+			serverp->port, serverp->bootstrap->bootstrap_port,
+			serverp->uid, serverp->cmd, 
+			((WIFEXITED(wstatus)) ? 
+			 "exited with non-zero status" :
+			 "exited as a result of signal"),
+			((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) : WTERMSIG(wstatus)),
+			serverp->pid);
+	}
+	serverp->pid = 0;
+
+	/*
+	 * Release the server task port reference, if we ever
+	 * got it in the first place.
+	 */
+	if (serverp->task_port != MACH_PORT_NULL) {
+		result = mach_port_deallocate(
+					mach_task_self(),
+					serverp->task_port);
+		if (result != KERN_SUCCESS)
+			kern_error(result, "mach_port_deallocate");
+		serverp->task_port = MACH_PORT_NULL;
+	}
+}
+
+static void
+demand_server(server_t *serverp)
+{
+	service_t *servicep;
+	kern_return_t result;
+
+	/*
+	 * For on-demand servers, make sure that the service ports are
+	 * back in on-demand portset.  Active service ports should come
+	 * back through a PORT_DESTROYED notification.  We only have to
+	 * worry about the inactive ports that may have been previously
+	 * pulled from the set but never checked-in by the server.
+	 */
+
+	for (  servicep = FIRST(services)
+			   ; !IS_END(servicep, services)
+			   ; servicep = NEXT(servicep))
+	{
+		if (serverp == servicep->server && !servicep->isActive) {
+			result = mach_port_move_member(
+							mach_task_self(),
+							servicep->port,
+							demand_port_set);
+			if (result != KERN_SUCCESS)
+				kern_fatal(result, "mach_port_move_member");
+		}
+	}
+}
+
+static
+void dispatch_server(server_t *serverp)
+{
+	if (!active_server(serverp)) {
+		if (useless_server(serverp))
+			delete_server(serverp);
+		else if (serverp->servertype == RESTARTABLE)
+			start_server(serverp);
+		else if (serverp->servertype == DEMAND)
+			demand_server(serverp);
+	}
+}
+
+void
+setup_server(server_t *serverp)
 {
 	kern_return_t result;
 	mach_port_t old_port;
-	task_port_t init_task;
-	int pid;
 	
-	/* get rid of any old server port (this might be a restart) */
-	old_port = serverp->port;
-	serverp->port = MACH_PORT_NULL;
-        if (old_port != MACH_PORT_NULL) {
-            msg_destroy_port(old_port);
-        }
 	/* Allocate privileged port for requests from service */
-	result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE ,&serverp->port);
-	info("Allocating port %d for server %s", serverp->port, serverp->cmd);
+	result = mach_port_allocate(mach_task_self(),
+						MACH_PORT_RIGHT_RECEIVE ,
+						&serverp->port);
+	info("Allocating port %x for server %s", serverp->port, serverp->cmd);
 	if (result != KERN_SUCCESS)	
 		kern_fatal(result, "port_allocate");
 
-        result = mach_port_insert_right(mach_task_self(), serverp->port, serverp->port, MACH_MSG_TYPE_MAKE_SEND);
-        if (result != KERN_SUCCESS)
-            kern_fatal(result, "mach_port_insert_right");
+	/* Request no-senders notification so we can tell when server dies */
+	result = mach_port_request_notification(mach_task_self(),
+						serverp->port,
+						MACH_NOTIFY_NO_SENDERS,
+						1,
+						serverp->port,
+						MACH_MSG_TYPE_MAKE_SEND_ONCE,
+						&old_port);
+	if (result != KERN_SUCCESS)
+		kern_fatal(result, "mach_port_request_notification");
+
 	/* Add privileged server port to bootstrap port set */
 	result = mach_port_move_member(mach_task_self(),
-				   serverp->port,
-				   bootstrap_port_set);
+						serverp->port,
+						bootstrap_port_set);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "mach_port_move_member");
+}
+
+static void
+start_server(server_t *serverp)
+{
+	kern_return_t result;
+	mach_port_t old_port;
+	int pid;
 
 	/*
 	 * Do what's appropriate to get bootstrap port setup in server task
 	 */
 	switch (serverp->servertype) {
-	case ETCINIT:
-		/*
-		 * This is pid 1 init program -- need to punch stuff
-		 * back into pid 1 task rather than create a new task
-		 */
-		result = task_for_pid(mach_task_self(), init_pid, &init_task);
-                if (result != KERN_SUCCESS)
-                    kern_fatal(result, "task_for_pid");
-		serverp->task_port = init_task;
-                unblock_init(init_task, serverp->port);
-		break;
 
 	case MACHINIT:
 		break;
 
 	case SERVER:
+	case DEMAND:
 	case RESTARTABLE:
+#ifdef DELAYED_BOOTSTRAP_DESTROY
+	  if (!serverp->port)
+#endif
+	      setup_server(serverp);
+
+	  serverp->activity = 0;
+
+	  /* Insert a send right */
+	  result = mach_port_insert_right(mach_task_self(),
+						serverp->port,
+						serverp->port,
+						MACH_MSG_TYPE_MAKE_SEND);
+	  if (result != KERN_SUCCESS)
+	  	kern_fatal(result, "mach_port_insert_right");
+
 		/* Give trusted service a unique bootstrap port */
-		result = task_set_bootstrap_port(mach_task_self(), serverp->port);
+		result = task_set_bootstrap_port(mach_task_self(),
+						 serverp->port);
 		if (result != KERN_SUCCESS)
 			kern_fatal(result, "task_set_bootstrap_port");
 
+		result = mach_port_deallocate(mach_task_self(),
+					      serverp->port);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_deallocate");
+
 		pid = fork();
-		if (pid < 0)
+		if (pid < 0) {
 			unix_error("fork");
-		else if (pid == 0) {	/* CHILD */
+		} else if (pid == 0) {	/* CHILD */
 			exec_server(serverp);
 			exit(1);
 		} else {		/* PARENT */
-			result = task_set_bootstrap_port(mach_task_self(),
-							 MACH_PORT_NULL);
+
+			result = task_set_bootstrap_port(
+							mach_task_self(),
+							MACH_PORT_NULL);
 			if (result != KERN_SUCCESS)
 				kern_fatal(result, "task_set_bootstrap_port");
 
-			result = task_for_pid(mach_task_self(),
-						  pid,
-						  &serverp->task_port);
-			if (result != KERN_SUCCESS)
-				kern_fatal(result, "getting server task port");
-			running_servers += 1;
+			info("Launched server %x in bootstrap %x uid %d: \"%s\": [pid %d]",
+			     serverp->port, serverp->bootstrap->bootstrap_port,
+				 serverp->uid, serverp->cmd, pid);
+			serverp->pid = pid;
+			result = task_for_pid(
+							mach_task_self(),
+							pid,
+							&serverp->task_port);
+			if (result != KERN_SUCCESS) {
+				kern_error(result, "getting server task port");
+				reap_server(serverp);
+				dispatch_server(serverp);
+				break;
+			}
+				
+			/* Request dead name notification to tell when task dies */
+			result = mach_port_request_notification(
+							mach_task_self(),
+							serverp->task_port,
+							MACH_NOTIFY_DEAD_NAME,
+							0,
+							notify_port,
+							MACH_MSG_TYPE_MAKE_SEND_ONCE,
+							&old_port);
+			if (result != KERN_SUCCESS) {
+				kern_error(result, "mach_port_request_notification");
+				reap_server(serverp);
+				dispatch_server(serverp);
+			}
 		}
 		break;
 	}
 }
 
-static void
-unblock_init(task_port_t task, mach_port_t newBootstrap)
-{
-	mach_msg_header_t init_go_msg;
-	kern_return_t result;
-
-	/*
-	 * Proc 1 is blocked in a msg_receive on its notify port, this lets
-	 * it continue, and we hand off its new bootstrap port
-	 */
-	init_go_msg.msgh_remote_port = inherited_bootstrap_port;
-	init_go_msg.msgh_local_port = newBootstrap;
-        init_go_msg.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND);
-        result = mach_msg(&init_go_msg, MACH_SEND_MSG, sizeof(init_go_msg), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-	if (result != KERN_SUCCESS)
-		kern_fatal(result, "unblock_init mach_msg(send) failed");
-	debug("sent go message");
-}
-
 static void
 exec_server(server_t *serverp)
 {
-	int nfds, fd;
-        char **argv;
-	
+	char **argv;
+	sigset_t mask;
+
 	/*
 	 * Setup environment for server, someday this should be Mach stuff
 	 * rather than Unix crud
 	 */
-	log("Initiating server %s [pid %d]", serverp->cmd, getpid());
 	argv = argvize(serverp->cmd);
-	nfds = getdtablesize();
-
-#ifdef notyet 
-	/*
-	 * If our priority's to be changed, set it up here.
-	 */
-	if (serverp->priority >= 0) {
-		kern_return_t result;
-		result = task_priority(mach_task_self(), serverp->priority,
-					 TRUE);
-		if (result != KERN_SUCCESS)
-			kern_error(result, "task_priority %d",
-				serverp->priority);
-	}
-#endif /* notyet */
 	close_errlog();
 
-	/*
-	 * Mark this process as an "init process" so that it won't be
-	 * blown away by init when it starts up (or changes states).
-	 */
-	if (init_pid == 1) {
-		debug("marking process %s as init_process\n", argv[0]);
-		init_process();
+	if (serverp->uid != inherited_uid)
+		if (setuid(serverp->uid) < 0)
+			unix_fatal("Disabled server %x bootstrap %x: \"%s\": setuid(%d)",
+					 serverp->port, serverp->bootstrap->bootstrap_port,
+					   serverp->cmd, serverp->uid);
+
+	if (setsid() < 0) {
+	  	/*
+		 * We can't keep this from happening, but we shouldn't start
+		 * the server not as a process group leader.  So, just fake like
+		 * there was real activity, and exit the child.  If needed,
+		 * we'll re-launch it under another pid.
+		 */
+		serverp->activity = 1;
+		unix_fatal("Temporary failure server %x bootstrap %x: \"%s\": setsid()",
+			   serverp->port, serverp->bootstrap->bootstrap_port,
+			   serverp->cmd);
 	}
 
-        for (fd =  debugging ? 3 : 0; fd < nfds; fd++)
-		close(fd);
-	fd = open("/dev/tty", O_RDONLY);
-	if (fd >= 0) {
-		ioctl(fd, TIOCNOTTY, 0);
-		close(fd);
-	}
+	sigemptyset(&mask);
+	(void) sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
 
-        execv(argv[0], argv);
-	unix_error("Can't exec %s", argv[0]);
+	execv(argv[0], argv);
+	unix_fatal("Disabled server %x bootstrap %x: \"%s\": exec()",
+			   serverp->port,
+			   serverp->bootstrap->bootstrap_port,
+			   serverp->cmd);
 }	
 
 static char **
@@ -676,284 +896,326 @@ argvize(const char *string)
 	return argv;
 }
 
+static void *
+demand_loop(void *arg)
+{
+	mach_msg_empty_rcv_t dummy;
+	kern_return_t dresult;
+
+
+	for(;;) {
+		mach_port_name_array_t members;
+		mach_msg_type_number_t membersCnt;
+		mach_port_status_t status;
+		mach_msg_type_number_t statusCnt;
+		int i;
+
+		/*
+		 * Receive indication of message on demand service
+		 * ports without actually receiving the message (we'll
+		 * let the actual server do that.
+		 */
+		dresult = mach_msg(
+							&dummy.header,
+							MACH_RCV_MSG|MACH_RCV_LARGE,
+							0,
+							0,
+							demand_port_set,
+							0,
+							MACH_PORT_NULL);
+		if (dresult != MACH_RCV_TOO_LARGE) {
+			kern_error(dresult, "demand_loop: mach_msg()");
+			continue;
+		}
+
+		/*
+		 * If we are shutting down, there is no use processing
+		 * any more of these messages.
+		 */
+		if (shutdown_in_progress == TRUE)
+			return arg;	
+
+		/*
+		 * Some port(s) now have messages on them, find out
+		 * which ones (there is no indication of which port
+		 * triggered in the MACH_RCV_TOO_LARGE indication).
+		 */
+		dresult = mach_port_get_set_status(
+							mach_task_self(),
+							demand_port_set,
+							&members,
+							&membersCnt);
+		if (dresult != KERN_SUCCESS) {
+			kern_error(dresult, "demand_loop: mach_port_get_set_status()");
+			continue;
+		}
+
+		for (i = 0; i < membersCnt; i++) {
+			statusCnt = MACH_PORT_RECEIVE_STATUS_COUNT;
+			dresult = mach_port_get_attributes(
+								mach_task_self(),
+								members[i],
+								MACH_PORT_RECEIVE_STATUS,
+								(mach_port_info_t)&status,
+								&statusCnt);
+			if (dresult != KERN_SUCCESS) {
+				kern_error(dresult, "demand_loop: mach_port_get_attributes()");
+				continue;
+			}
+
+			/*
+			 * For each port with messages, take it out of the
+			 * demand service portset, and inform the main thread
+			 * that it might have to start the server responsible
+			 * for it.
+			 */
+			if (status.mps_msgcount) {
+				dresult = mach_port_move_member(
+								mach_task_self(),
+								members[i],
+								MACH_PORT_NULL);
+				if (dresult != KERN_SUCCESS) {
+					kern_error(dresult, "demand_loop: mach_port_move_member()");
+					continue;
+				}
+				notify_server_loop(members[i]);
+			}
+		}
+
+		dresult = vm_deallocate(
+						mach_task_self(),
+						(vm_address_t) members,
+						(vm_size_t) membersCnt * sizeof(mach_port_name_t));
+		if (dresult != KERN_SUCCESS) {
+			kern_error(dresult, "demand_loop: vm_deallocate()");
+			continue;
+		}
+	}
+	return NULL;
+}
+								
 /*
- * server_loop -- pick requests off our service port and process them
+ * server_demux -- processes requests off our service port
  * Also handles notifications
  */
-#define	bootstrapMaxRequestSize	1024
-#define	bootstrapMaxReplySize	1024
 
-static void
-server_loop(void)
+static boolean_t
+server_demux(
+	mach_msg_header_t *Request,
+	mach_msg_header_t *Reply)
 {
     bootstrap_info_t *bootstrap;
     service_t *servicep;
     server_t *serverp;
     kern_return_t result;
-    mach_port_name_t previous;
-    mach_port_array_t array;
-    mach_msg_type_number_t count;
-    int i;
+	mig_reply_error_t *reply;
         
-    union {
-    	mach_msg_header_t hdr;
-	char body[bootstrapMaxRequestSize];
-    } msg;
-    union {
-    	mach_msg_header_t hdr;
-#ifdef notyet
-	death_pill_t death;
-#endif /* notyet */
-	char body[bootstrapMaxReplySize];
-    } reply;
-	    
-    for (;;) {
-	memset(&msg, 0, sizeof(msg));
-        result = mach_msg_overwrite_trap(&msg.hdr, MACH_RCV_MSG|MACH_RCV_INTERRUPT|MACH_RCV_TIMEOUT, 0, sizeof(msg), bootstrap_port_set, 500, MACH_PORT_NULL, MACH_MSG_NULL, 0);
-	if (result != KERN_SUCCESS) {
-            if (result != MACH_RCV_TIMED_OUT) {
-                kern_error(result, "server_loop: msg_receive()");
-            }
-	    continue;
-	}
+	debug("received message on port %x\n", Request->msgh_local_port);
 
-#if	DEBUG
-	debug("received message on port %d\n", msg.hdr.msgh_local_port);
-#endif	DEBUG
+	/*
+	 * Do minimal cleanup and then exit.
+	 */
+	if (shutdown_in_progress == TRUE) {
+		log("Shutting down. Deactivating root bootstrap (%x) ...",
+			bootstraps.bootstrap_port);
+		deactivate_bootstrap(&bootstraps);
+		log("Done.");
+		exit(0);
+	}
+					
+	reply = (mig_reply_error_t *)Reply;
 
 	/*
 	 * Pick off notification messages
 	 */
-	if (msg.hdr.msgh_local_port == notify_port) {
-	    mach_port_name_t np;
-
-            switch (msg.hdr.msgh_id) {
-	    case MACH_NOTIFY_DEAD_NAME:
-                np = ((mach_dead_name_notification_t *)&msg)->not_port;
-#if	DEBUG
-		info("Notified dead name %d", np);
-#endif	DEBUG
-		if (np == inherited_bootstrap_port)
-		{
-		    inherited_bootstrap_port = MACH_PORT_NULL;
-		    forward_ok = FALSE;
-		    break;
-		}
+	if (Request->msgh_local_port == notify_port) {
+		mach_port_name_t np;
+
+		memset(reply, 0, sizeof(*reply));
+		switch (Request->msgh_id) {
+		case MACH_NOTIFY_DEAD_NAME:
+			np = ((mach_dead_name_notification_t *)Request)->not_port;
+			debug("Notified dead name %x", np);
+
+			if (np == inherited_bootstrap_port) {
+				inherited_bootstrap_port = MACH_PORT_NULL;
+				forward_ok = FALSE;
+			}
 		
-		/*
-		 * This may be notification that the task_port associated
-		 * with a task we've launched has been deleted.  This
-		 * happens only when the server dies.
-		 */
-		serverp = lookup_server_by_task_port(np);
-		if (serverp != NULL) {
-		    info("Notified that server %s died\n", serverp->cmd);
-		    if (running_servers <= 0) {
-			    /* This "can't" happen */
-			    running_servers = 0;
-			    error("task count error");
-		    } else {
-			    running_servers -= 1;
-			    log("server %s died",
-				serverp != NULL ? serverp->cmd : "Unknown");
-			    if (serverp != NULL) {
-				    /*
-				     * FIXME: need to control execs
-				     * when server fails immediately
-				     */
-				    if (   serverp->servertype == RESTARTABLE
-					/*
-					&& haven't started this recently */)
-					    start_server(serverp);
-			    }
-		    }
-		    break;
-		}
+			/*
+			 * Check to see if a subset requestor port was deleted.
+			 */
+			while (bootstrap = lookup_bootstrap_by_req_port(np)) {
+				debug("Received dead name notification for bootstrap subset %x requestor port %x",
+					 bootstrap->bootstrap_port, bootstrap->requestor_port);
+				mach_port_deallocate(
+									 mach_task_self(),
+									 bootstrap->requestor_port);
+				bootstrap->requestor_port = MACH_PORT_NULL;
+				deactivate_bootstrap(bootstrap);
+			}
 
-		/*
-		 * Check to see if a subset requestor port was deleted.
-		 */
-		while (bootstrap = lookup_bootstrap_req_by_port(np)) {
-			info("notified that requestor of subset %d died",
-				bootstrap->bootstrap_port);
-			delete_bootstrap(bootstrap);
-		}
+			/*
+			 * Check to see if a defined service has gone
+			 * away.
+			 */
+			while (servicep = lookup_service_by_port(np)) {
+				/*
+				 * Port gone, registered service died.
+				 */
+				debug("Received dead name notification for service %s "
+					  "on bootstrap port %x\n",
+					  servicep->name, servicep->bootstrap);
+				debug("Service %s failed - deallocate", servicep->name);
+				delete_service(servicep);
+			}
 
-		/*
-		 * Check to see if a defined service has gone
-		 * away.
-		 */
-		while (servicep = lookup_service_by_port(np)) {
-		    /*
-		     * Port gone, server died.
-		     */
-		    debug("Received destroyed notification for service %s "
-			  "on bootstrap port %d\n",
-			  servicep->name, servicep->bootstrap);
-		    if (servicep->servicetype == REGISTERED) {
-			debug("Service %s failed - deallocate", servicep->name);
-			mach_port_deallocate(mach_task_self(),np);
-			mach_port_deallocate(mach_task_self(),servicep->port);
-			delete_service(servicep);
-		    } else {
 			/*
-			 * Allocate a new, backed-up port for this service.
+			 * Check to see if a launched server task has gone
+			 * away.
 			 */
-			log("Service %s failed - re-initialize",
-			    servicep->name);
-			msg_destroy_port(servicep->port);
-			result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &servicep->port);
-			if (result != KERN_SUCCESS)
-				kern_fatal(result, "port_allocate");
-                        result = mach_port_insert_right(bootstrap_self, servicep->port, servicep->port, MACH_MSG_TYPE_MAKE_SEND);
-                        if (result != KERN_SUCCESS)
-                                kern_fatal(result, "mach_port_insert_right");
-#if 0
-                        result = port_set_backup(mach_task_self(),
-						    servicep->port,
-						    backup_port,
-						    &previous);
-			if (result != KERN_SUCCESS)
-				kern_fatal(result, "port_set_backup");
-#endif
-                        servicep->isActive = FALSE;
-		    }
+			if (serverp = lookup_server_by_task_port(np)) {
+				/*
+				 * Port gone, server died.
+				 */
+				debug("Received task death notification for server %s ",
+					  serverp->cmd);
+				reap_server(serverp);
+				dispatch_server(serverp);
+			}
+
+			mach_port_deallocate(mach_task_self(), np);
+			reply->RetCode = KERN_SUCCESS;
+			break;
+
+		case MACH_NOTIFY_PORT_DELETED:
+			np = ((mach_port_deleted_notification_t *)Request)->not_port;
+			debug("port deleted notification on 0x%x\n", np);
+			reply->RetCode = KERN_SUCCESS;
+			break;
+
+		case MACH_NOTIFY_SEND_ONCE:
+			debug("notification send-once right went unused\n");
+			reply->RetCode = KERN_SUCCESS;
+			break;
+
+		default:
+			error("Unexpected notification: %d", Request->msgh_id);
+			reply->RetCode = KERN_FAILURE;
+			break;
 		}
-		break;
-	    default:
-		error("Unexpected notification: %d", msg.hdr.msgh_id);
-		break;
-	    }
-	}
-#if 0
-        else if (msg.hdr.msg_local_port == backup_port) {
-	    notification_t *not = (notification_t *) &msg.hdr;
-	    mach_port_name_t np = not->notify_port;
-
-	    /*
-	     * Port sent back to us, server died.
-	     */
-	    info("port %d returned via backup", np);
-	    servicep = lookup_service_by_port(np);
-	    if (servicep != NULL) {
-	        debug("Received %s notification for service %s",
-		      not->notify_header.msg_id
-		      == NOTIFY_PORT_DESTROYED
-		      ? "destroyed" : "receive rights",
-		      servicep->name);
-		log("Service %s failed - port backed-up", servicep->name);
-		ASSERT(canReceive(servicep->port));
-		servicep->isActive = FALSE;
-		result = port_set_backup(mach_task_self(),
-					 servicep->port,
-					 backup_port,
-					 &previous);
-		if (result != KERN_SUCCESS)
-			kern_fatal(result, "port_set_backup");
-	    } else
-	    	msg_destroy_port(np);
 	}
-#endif
-        else
-            {	/* must be a service request */
-            bootstrap_server(&msg.hdr, &reply.hdr);
-#ifdef	DEBUG
-	    debug("Handled request.");
-#endif	DEBUG
-		reply.hdr.msgh_local_port = MACH_PORT_NULL;
-                result = mach_msg(&reply.hdr, MACH_SEND_MSG|MACH_SEND_TIMEOUT, reply.hdr.msgh_size, 0, MACH_PORT_NULL,
-				  BOOTSTRAP_REPLY_TIMEOUT, MACH_PORT_NULL);
-#ifdef	DEBUG
-		debug("Reply sent.");
-#endif	DEBUG
-                if (result != MACH_MSG_SUCCESS) {
-		    kern_error(result, "msg_send");
-                }
-            }
-	/* deallocate uninteresting ports received in message */
-	msg_destroy(&msg.hdr);
-    }
-}
 
-/*
- * msg_destroy -- walk through a received message and deallocate any
- * useless ports or out-of-line memory
- */
-static void
-msg_destroy(mach_msg_header_t *m)
-{
-#ifdef notyet /* [ */
-	msg_type_t *mtp;
-	msg_type_long_t *mtlp;
-	void *dp;
-	unsigned type, size, num;
-	boolean_t inlne;
-	mach_port_t *pp;
-	kern_return_t result;
+	else if (Request->msgh_local_port == backup_port) {
+		mach_port_name_t np;
+
+		memset(reply, 0, sizeof(*reply));
+
+		np = ((mach_port_destroyed_notification_t *)Request)->not_port.name; 
+		servicep = lookup_service_by_port(np);
+		if (servicep != NULL) {
+			server_t *serverp = servicep->server;
+
+			switch (Request->msgh_id) {
+
+			case MACH_NOTIFY_PORT_DESTROYED:
+				/*
+				 * Port sent back to us, server died.
+				 */
+				debug("Received destroyed notification for service %s",
+					  servicep->name);
+				debug("Service %x bootstrap %x backed up: %s",
+				     servicep->port, servicep->bootstrap->bootstrap_port,
+					 servicep->name);
+				ASSERT(canReceive(servicep->port));
+				servicep->isActive = FALSE;
+				serverp->active_services--;
+				dispatch_server(serverp);
+				reply->RetCode = KERN_SUCCESS;
+				break;
 
-	msg_destroy_port(m->msg_remote_port);
-	for (  mtp = (msg_type_t *)(m + 1)
-	     ; (unsigned)mtp - (unsigned)m < m->msg_size
-	     ;)
-	{
-		inlne = mtp->msg_type_inline;
-		if (mtp->msg_type_longform) {
-			mtlp = (msg_type_long_t *)mtp;
-			type = mtlp->msg_type_long_name;
-			size = mtlp->msg_type_long_size;
-			num = mtlp->msg_type_long_number;
-			dp = (void *)(mtlp + 1);
+			case DEMAND_REQUEST:
+				/* message reflected over from demand start thread */
+				if (!active_server(serverp))
+					start_server(serverp);
+				reply->RetCode = KERN_SUCCESS;
+				break;
+
+			default:
+				debug("Mysterious backup_port notification %d", Request->msgh_id);
+				reply->RetCode = KERN_FAILURE;
+				break;
+			}
 		} else {
-			type = mtp->msg_type_name;
-			size = mtp->msg_type_size;
-			num = mtp->msg_type_number;
-			dp = (void *)(mtp + 1);
+			debug("Backup_port notification - previously deleted service");
+			reply->RetCode = KERN_FAILURE;
 		}
-		if (inlne)
-			mtp = (msg_type_t *)(dp + num * (size/BITS_PER_BYTE));
-		else {
-			mtp = (msg_type_t *)(dp + sizeof(void *));
-			dp = *(char **)dp;
-		}
-		if (MSG_TYPE_PORT_ANY(type)) {
-			for (pp = (mach_port_t *)dp; num-- > 0; pp++)
-				msg_destroy_port(*pp);
-		}
-		if ( ! inlne ) {
-			result = vm_deallocate(mach_task_self(), (vm_address_t)dp,
-			 num * (size/BITS_PER_BYTE));
-			if (result != KERN_SUCCESS)
-				kern_error(result,
-					   "vm_deallocate: msg_destroy");
+	}
+
+	else if (Request->msgh_id == MACH_NOTIFY_NO_SENDERS) {
+		mach_port_t ns = Request->msgh_local_port;
+
+		if ((serverp = lookup_server_by_port(ns)) != NULL_SERVER) {
+	  		/*
+			 * A server we launched has released his bootstrap
+			 * port send right.  We won't re-launch him unless
+			 * his services came back to roost.  But we need to
+			 * destroy the bootstrap port for fear of leaking.
+			 */
+			debug("server %s dropped server port", serverp->cmd);
+			serverp->port = MACH_PORT_NULL;
+			dispatch_server(serverp);
+		} else if (bootstrap = lookup_bootstrap_by_port(ns)) {
+			/*
+			 * The last direct user of a deactivated bootstrap went away.
+			 * We can finally free it.
+			 */
+			debug("Deallocating bootstrap %x: no more clients", ns);
+			bootstrap->bootstrap_port = MACH_PORT_NULL;
+			deallocate_bootstrap(bootstrap);
 		}
+		
+		result = mach_port_mod_refs(
+						mach_task_self(),
+						ns,
+						MACH_PORT_RIGHT_RECEIVE,
+						-1);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_mod_refs");
+
+		memset(reply, 0, sizeof(*reply));
+		reply->RetCode = KERN_SUCCESS;
+	}
+     
+	else {	/* must be a service request */
+		debug("Handled request.");
+		return bootstrap_server(Request, Reply);
 	}
-#endif /* notyet ] */
+	return TRUE;
 }
 
 /*
- * msg_destroy_port -- deallocate port if it's not important to bootstrap
- * Bad name, this is used for things other than msg_destroy.
+ * server_loop -- pick requests off our service port and process them
+ * Also handles notifications
  */
-void
-msg_destroy_port(mach_port_t p)
+#define	bootstrapMaxRequestSize	1024
+#define	bootstrapMaxReplySize	1024
+
+static void
+server_loop(void)
 {
-	if (   p == MACH_PORT_NULL
-	    || p == mach_task_self()
-	    || p == mig_get_reply_port()
-	    || p == bootstrap_port_set
-	    || p == inherited_bootstrap_port
-	    || lookup_service_by_port(p)
-	    || lookup_server_by_port(p)
-	    || lookup_bootstrap_by_port(p) != &bootstraps
-	    || lookup_bootstrap_req_by_port(p) != &bootstraps
-	    || p == bootstraps.bootstrap_port
-	    || p == bootstraps.requestor_port)
-		return;
-
-#if	DEBUG
-	debug("Deallocating port %d", p);
-#endif	DEBUG
-	(void) mach_port_deallocate(mach_task_self(), p);
+	mach_msg_return_t mresult;
+
+	for (;;) {
+		mresult = mach_msg_server(
+						server_demux,
+						bootstrapMaxRequestSize,
+						bootstrap_port_set,
+                        MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER)|
+                        MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0));
+		if (mresult != MACH_MSG_SUCCESS)
+				kern_error(mresult, "mach_msg_server");
+	}
 }
 
 boolean_t
@@ -984,44 +1246,3 @@ canSend(mach_port_t port)
 	}
 	return ((p_type & MACH_PORT_TYPE_PORT_RIGHTS) != 0);
 }
-void
-set_default_policy(
-	mach_port_t master_host_port)
-{
-#if 0
-    host_priority_info_data_t	host_pri_info;
-	mach_port_t		default_processor_set_name;
-	mach_port_t		default_processor_set;
-	policy_rr_base_data_t	rr_base;
-	policy_rr_limit_data_t	rr_limit;
-	kern_return_t		result;
-	mach_msg_type_number_t	count;
-	static char here[] = "default_pager_set_policy";
-
-	count = HOST_PRIORITY_INFO_COUNT;
-	result = host_info(mach_host_self(),
-		      HOST_PRIORITY_INFO,
-		      (host_info_t) &host_pri_info,
-		      &count);
-	if (result != KERN_SUCCESS)
-		kern_fatal(result, "Could not get host priority info");
-
-	rr_base.quantum = 0;
-	rr_base.base_priority = host_pri_info.system_priority;
-	rr_limit.max_priority = host_pri_info.system_priority;
-
-	(void)processor_set_default(mach_host_self(),
-				    &default_processor_set_name);
-	(void)host_processor_set_priv(master_host_port,
-				      default_processor_set_name,
-				      &default_processor_set);
-
-	result = task_set_policy(mach_host_self(), default_processor_set,
-			    POLICY_RR,
-			    (policy_base_t) & rr_base, POLICY_RR_BASE_COUNT,
-			    (policy_limit_t) & rr_limit, POLICY_RR_LIMIT_COUNT,
-			    TRUE);
-	if (result != KERN_SUCCESS)
-		kern_fatal(result, "Could not set task policy ");
-#endif
-}
diff --git a/mach_init.tproj/bootstrap.defs b/mach_init.tproj/bootstrap.defs
index 99af0cc..43a0b60 100644
--- a/mach_init.tproj/bootstrap.defs
+++ b/mach_init.tproj/bootstrap.defs
@@ -37,19 +37,15 @@ subsystem bootstrap 400;
  *  The bootstrap server is the first user-mode task initiated by the Mach
  *  kernel at system boot time.  The bootstrap server provides two services,
  *  it initiates other system tasks, and manages a table of name-port bindings
- *  for fundamental system services  (e.g. the NetMsgServer, and the Unix
- *  emulation service).
- *
- *  The file /etc/bootstrap.conf is read by bootstrap to determine other system
- *  services to initiate at system boot time.  The format of this file is
- *  described later.
+ *  for fundamental system services  (e.g. lookupd, Window Manager, etc...).
  *
  *  Name-port bindings can be established with the bootstrap server by either 
  *  of two mechanisms:
  *
- *  1.  The binding can be indicated in the file /etc/bootstrap.conf.  In this
- *  case, bootstrap will immediately create a port and bind the indicated name
- *  with that port.  At a later time, a service may "checkin" for the name-port
+ *  1.  The binding can be indicated, in advance of the service that backs it
+ *  being available, via a "service create" request.  In this case, bootstrap
+ *  will immediately create a port and bind the indicated name with that port.
+ *  At a later time, a service may "checkin" for the name-port
  *  binding and will be returned receive rights for the bound port.  Lookup's
  *  on bindings created by this mechanism will return send rights to the port,
  *  even if no service has "checked-in".  In this case, requests sent to the
@@ -73,98 +69,112 @@ subsystem bootstrap 400;
  *  it is marked available for check-out again.  This allows crashed servers to 
  *  resume service to previous clients.  Lookup's on this named port will 
  *  continue to be serviced by bootstrap while holding receive rights for the 
- *  bound port.  A client may detect that the service is inactive via the.
- *  bootstrap status request.  If the service re-registers rather than
- *  "checking-in" the original bound port is destroyed.
+ *  bound port.  A client may detect that the service is inactive via the
+ *  bootstrap status request.  If an inactive service re-registers rather
+ *  than "checking-in" the original bound port is destroyed.
  *
  *  The status of a named service may be obtained via the "status" request.
  *  A service is "active" if a name-port binding exists and receive rights
  *  to the bound port are held by a task other than bootstrap.
  *
- *  Bootstrap initiates server tasks and creates initial name-port bindings as
- *  directed by the configuration file /etc/bootstrap.conf.  This file has
- *  entries with the following formats:
- *
- *	services [ SERVICE_NAME ]+ ;
- *
- *		E.g:
- *		services OldService=1 SomeService;
- *
- *		Creates a port and binds the name "OldService" to it.
- *		For compatability, assigns the port via mach_ports_register to
- *		slot 1.  Also creates a port and binds the name "SomeService".
- *
- *	self [ SERVICE_NAME ]+ ;
- *
- *		E.g:
- *		self BootStrapService;
- *
- *		Provides a binding to bootstrap's own service port named
- *		"BootStrapService".
- *
- *	[restartable] server SERVER_FILE_AND_ARGS [ services ... ] ;
- *
- *		E.g:
- *		server "/usr/etc/sigserver -i" services UnixSignalService;
- *
- *		Initiates the server task "/usr/etc/sigserver" with
- *		command-line argument "-i", and also creates a name-port
- *		binding for the name UnixSignalService.  Checkin requests for
- *		UnixSignalService are only accepted via the bootstrap service
- *		port passed to/usr/etc/sigserver.  If the "restartable" option
- *		had been specified, bootstrap will reinitiate the server task
- *		if it receives notification that all of the server's service
- *		ports have been destroyed or deallocated.  The server command
- *		may be specified without surrounding quotes if it does not
- *		include blanks.
- *
- *	init SERVER_FILE_AND_ARGS [ services ... ] ;
- *
- *		E.g:
- *		init /etc/init services NetMsgService=0 PSWindowService=4;
- *
- *		Functions like "server" request above, except process is
- *		started as pid 1.  Illegal if bootstrap itself was not
- *		initiated as pid 1.
- *
- *	forward;
- *
- *		If present, bootstrap will forward unknown lookup requests to
- *		its bootstrap service port (if not PORT_NULL), and forward any
- *		reply to the original requester.
- *
- *	# Comment string up to end of line.
- *
- *		A line terminated comment starts with a sharp sign (#).
- *
- *  Lexical notes:  Strings are either enclosed in double quotes ("), or must
- *  start with a letter or underscore (_) and followed by a string of
- *  alphanumerics and underscores; backslash (\) escapes the following
- *  character.  Strings are limited to a (large) length.  Numbers must be
- *  decimal.  Blanks and newlines may be freely used outside of strings.
+ *  The bootstrap server may also (re)start server processes associated with
+ *  with a set of services. The definition of the server process is done
+ *  through the "create server" request.  The server will be launched in the
+ *  same bootstrap context in which it was registered.
  */
 
 #include <mach/std_types.defs>
+#include <mach/mach_types.defs>
 import <servers/bootstrap_defs.h>;
 
-type name_t		= c_string[128];
-type name_array_t	= ^array [] of name_t;
-type bool_array_t	= ^array [] of boolean_t;
+type cmd_t			= c_string[512];
+type name_t			= c_string[128];
+type cmd_array_t		= ^array [] of cmd_t;
+type name_array_t		= ^array [] of name_t;
+type bootstrap_status_t		= integer_t;
+type bootstrap_status_array_t	= ^array [] of bootstrap_status_t;
 
 serverprefix x_;
 
-/*  old service_checkin */
-skip;
-/*  old service_status */
-skip;
+/*
+ * kern_return_t
+ * bootstrap_create_server(mach_port_t bootstrap_port,
+ *		      	cmd_t server_command,
+ *			integer_t server_uid,
+ *			boolean_t on_demand,
+ *			mach_port_t *server_port)
+ *
+ * Declares a server that mach_init will re-spawn within the specified
+ * bootstrap context.  The server is considered already "active"
+ * (i.e. will not be re-spawned) until the returned server_port is
+ * deallocated.
+ *
+ * In the meantime, services can be declared against the server,
+ * by using the server_port as the privileged bootstrap target of
+ * subsequent bootstrap_create_service() calls.
+ *
+ * When mach_init re-spawns the server, its task bootstrap port
+ * is set to the privileged sever_port.  Through this special
+ * bootstrap port, it can access all of parent bootstrap's context
+ * (and all services are created in the parent's namespace). But
+ * all additional service declarations (and declaration removals)
+ * will be associated with this particular server.
+ *
+ * Only a holder of the server_port privilege bootstrap port can
+ * check in or register over those services.  
+ *
+ * When all services associated with a server are deleted, and the server
+ * exits, it will automatically be deleted itself.
+ *
+ * If the server is declared "on_demand," then a non-running server
+ * will be re-launched on first use of one of the service ports
+ * registered against it.  Otherwise, it will be re-launched
+ * immediately upon exiting (whether any client is actively using
+ * any of the service ports or not).
+ *
+ * Errors:	Returns appropriate kernel errors on rpc failure.
+ *		Returns BOOTSTRAP_NOT_PRIVILEGED, bootstrap or uid invalid.
+ */
+routine bootstrap_create_server(
+		bootstrap_port	: mach_port_t;
+		server_cmd	: cmd_t;
+		server_uid	: integer_t;
+		on_demand	: boolean_t;
+ ServerSecToken	token		: security_token_t;
+	out	server_port	: mach_port_make_send_t);
+
+/*
+ * kern_return_t
+ * bootstrap_unprivileged(mach_port_t bootstrap_port,
+ *			  mach_port_t *unpriv_port)
+ *
+ * Given a bootstrap port, return its unprivileged equivalent.  If
+ * the port is already unprivileged, another reference to the same
+ * port is returned.
+ *
+ * This is most often used by servers, which are launched with their
+ * bootstrap port set to the privileged port for the server, to get
+ * an unprivileged version of the same port for use by its unprivileged
+ * children (or any offspring that it does not want to count as part
+ * of the "server" for mach_init registration and re-launch purposes).
+ */
+routine bootstrap_unprivileged(
+		bootstrap_port	: mach_port_t;
+	out	unpriv_port	: mach_port_t);
 
 /*
  * kern_return_t
  * bootstrap_check_in(mach_port_t bootstrap_port,
  *		     name_t service_name,
- *		     port_all_t *service_port)
+ *		     mach_port_t *service_port)
  *
- * Returns all rights to service_port of service named by service_name.
+ * Returns the receive right for the service named by service_name. The
+ * service must have previously been declared in this bootstrap context via
+ * a call to bootstrap_create_service().  Attempts to check_in a service
+ * which is already active are not allowed.
+ *
+ * If the service was declared as being associated with a server, the
+ * check_in must come from the server's privileged port (server_port).
  *
  * Errors:	Returns appropriate kernel errors on rpc failure.
  *		Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
@@ -184,14 +194,15 @@ routine bootstrap_check_in(
  *		      name_t service_name,
  *		      mach_port_t service_port)
  *
- * Registers send rights for the port service_port for the service named by
- * service_name.  Attempts to registering a service where an active binding
- * already exists are rejected.  On the otherhand, registering a service where
- * and inactive binding exists (i.e. bootstrap currently holds receive rights
- * for the service port) is allowed; in this case the previous service port
- * will be deallocated.  Restarting services wishing to resume service for
- * previous clients must first attempt to checkin to the service in order to
- * recover the previous service port.
+ * Registers a send right for service_port with the service identified by
+ * service_name.  Attempts to register a service where an active binding
+ * already exists are rejected.
+ *
+ * If the service was previously declared with bootstrap_create_service(),
+ * but is not currently active, this call can be used to undeclare the
+ * service. The bootstrap port used must have sufficient privilege to
+ * do so.  (Registering MACH_PORT_NULL is especially useful for shutting
+ * down declared services).
  *
  * Errors:	Returns appropriate kernel errors on rpc failure.
  *		Returns BOOTSTRAP_NOT_PRIVILEGED, if request directed to
@@ -210,8 +221,9 @@ routine bootstrap_register(
  *		    name_t service_name,
  *		    mach_port_t *service_port)
  *
- * Returns send rights for the service port of the service named by
- * service_name in service_port.  Service is not guaranteed to be active.
+ * Returns a send right for the service port declared/registered under the
+ * name service_name. The service is not guaranteed to be active.  Use the
+ * bootstrap_status call to determine the status of the service.
  *
  * Errors:	Returns appropriate kernel errors on rpc failure.
  *		Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
@@ -249,16 +261,33 @@ routine bootstrap_look_up_array(
 	out	service_ports	: mach_port_array_t;
 	out	all_services_known: boolean_t);
 
-/*  old bootstrap_get_unpriv_port */
-skip;
+/*
+ * kern_return_t
+ * bootstrap_parent(mach_port_t bootstrap_port,
+ *		    mach_port_t *parent_port);
+ *
+ * Given a bootstrap subset port, return the parent bootstrap port.
+ * If the specified bootstrap port is already the root subset,
+ * MACH_PORT_NULL will be returned.
+ *
+ * Errors:
+ *	Returns BOOTSTRAP_NOT_PRIVILEGED if the caller is not running
+ *	with an effective user id of root (as determined by the security
+ *	token in the message trailer).
+ */
+routine bootstrap_parent(
+		bootstrap_port	: mach_port_t;
+ ServerSecToken	token		: security_token_t;
+	out	parent_port	: mach_port_t);
 
 /*
  * kern_return_t
  * bootstrap_status(mach_port_t bootstrap_port,
  *		    name_t service_name,
- *		    boolean_t *service_active);
+ *		    bootstrap_status_t *service_active);
  *
- * Returns: service_active is true if service is available.
+ * Returns: service_active indicates if service is active, inactive, or
+ *	    associated with a launch-on-demand server.
  *			
  * Errors:	Returns appropriate kernel errors on rpc failure.
  *		Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
@@ -266,7 +295,7 @@ skip;
 routine bootstrap_status(
 		bootstrap_port	:	mach_port_t;
 		service_name	:	name_t;
-	out	service_active	:	boolean_t);
+	out	service_active	:	bootstrap_status_t);
 
 /*
  * kern_return_t
@@ -284,7 +313,7 @@ routine bootstrap_info(
 		bootstrap_port	: mach_port_t;
 	out	service_names	: name_array_t, dealloc;
 	out server_names	: name_array_t, dealloc;
-	out service_active	: bool_array_t, dealloc);
+	out service_active	: bootstrap_status_array_t, dealloc);
 
 /*
  * kern_return_t
@@ -301,7 +330,7 @@ routine bootstrap_info(
  * registered with an ancestor port may be registered with the subset port
  * are allowed.  Services already advertised may then be effectively removed
  * by registering PORT_NULL for the service.
- * When it is detected that the requestor_port is destroied the subset
+ * When it is detected that the requestor_port is destroyed the subset
  * port and all services advertized by it are destroied as well.
  *
  * Errors:	Returns appropriate kernel errors on rpc failure.
@@ -328,3 +357,4 @@ routine bootstrap_create_service(
 		bootstrap_port	: mach_port_t;
 		service_name	: name_t;
 	out	service_port	: mach_port_t);
+
diff --git a/mach_init.tproj/bootstrap_internal.h b/mach_init.tproj/bootstrap_internal.h
index b494e93..bf81925 100644
--- a/mach_init.tproj/bootstrap_internal.h
+++ b/mach_init.tproj/bootstrap_internal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-1999 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -31,23 +31,26 @@
 
 #import <mach/mach.h>
 #import <mach/boolean.h>
+#import <mach/notify.h>
 
-#define BASEPRI_USER	10	/* AOF Thu Feb 16 14:42:57 PST 1995 */
+#define BASEPRI_USER	31	/* AOF 20/02/2002 */
 
 #define	BITS_PER_BYTE	8	/* this SHOULD be a well defined constant */
 #define	ANYWHERE	TRUE	/* For use with vm_allocate() */
 
+#define DEMAND_REQUEST	MACH_NOTIFY_LAST	/* demand service messaged */
+
+#define DELAYED_BOOTSTRAP_DESTROY TRUE		/* destroyed on last reference */
+
 extern const char *program_name;
-extern const char *conf_file;
-extern const char *default_conf;
 extern mach_port_t lookup_only_port;
 extern mach_port_t inherited_bootstrap_port;
 extern mach_port_t self_port;		/* Compatability hack */
 extern boolean_t forward_ok;
 extern boolean_t debugging;
 extern mach_port_t bootstrap_port_set;
-extern int init_priority;
+extern mach_port_t demand_port_set;
+extern mach_port_t notify_port;
+extern mach_port_t backup_port;
 extern boolean_t canReceive(mach_port_t port);
 extern boolean_t canSend(mach_port_t port);
-
-extern void msg_destroy_port(mach_port_t p);
diff --git a/mach_init.tproj/error_log.c b/mach_init.tproj/error_log.c
index 599e4d9..183abfc 100644
--- a/mach_init.tproj/error_log.c
+++ b/mach_init.tproj/error_log.c
@@ -43,50 +43,53 @@
 #import "error_log.h"
 
 static pthread_mutex_t errlog_lock = PTHREAD_MUTEX_INITIALIZER;
+static boolean_t stderr_open = FALSE;
+static boolean_t log_stopped = FALSE;
 
 void
-init_errlog(boolean_t is_init)
+init_errlog(boolean_t daemon)
 {
 	int nfds, fd;
 
-	if (is_init) {
-		close(0);
-		freopen("/dev/console", "r", stdin);
-		setbuf(stdin, NULL);
-		close(1);
-		freopen("/dev/console", "w", stdout);
-		setbuf(stdout, NULL);
-		close(2);
-		freopen("/dev/console", "w", stderr);
-		setbuf(stderr, NULL);
+	if (!daemon) {
+		stderr_open = TRUE; 
+		nfds = getdtablesize();
+		for (fd = 3; fd < nfds; fd++)
+			close(fd);
+	} else {
+		openlog((char *)program_name, LOG_PID|LOG_CONS, LOG_DAEMON);
+		setlogmask(LOG_UPTO(LOG_DEBUG)); /* we'll do our own filtering */
 	}
+}
 
-	nfds = getdtablesize();
-	for (fd = 3; fd < nfds; fd++)
-		close(fd);
-	openlog((char *)program_name, LOG_PID, LOG_DAEMON);
-	setlogmask(LOG_UPTO(LOG_INFO));
+void
+stop_errlog(void)
+{
+	log_stopped = TRUE;
 }
 
 void
 close_errlog(void)
 {
+	stop_errlog();
 	closelog();
 }
 
 static void do_log(const int level, const char *format, va_list ap)
 {
-	pthread_mutex_lock(&errlog_lock);
-	if (debugging) {
-		fprintf(stderr, "%s[%d]%s: ",
-			level == LOG_ALERT ? " FATAL" : "",
-			getpid(), program_name);
-		vfprintf(stderr, format, ap);
-		fprintf(stderr, "\n");
-	} else {
-		vsyslog(level, format, ap);
+	if (!log_stopped && (debugging || level <= LOG_NOTICE)) {
+		pthread_mutex_lock(&errlog_lock);
+		if (stderr_open) {
+			fprintf(stderr, "%s[%d]%s: ",
+				level == LOG_ALERT ? " FATAL" : "",
+				getpid(), program_name);
+			vfprintf(stderr, format, ap);
+			fprintf(stderr, "\n");
+		} else {
+			vsyslog(level, format, ap);
+		}
+		pthread_mutex_unlock(&errlog_lock);
 	}
-	pthread_mutex_unlock(&errlog_lock);
 }
 
 void debug(const char *format, ...)
diff --git a/mach_init.tproj/error_log.h b/mach_init.tproj/error_log.h
index 027ab75..f6dc4df 100644
--- a/mach_init.tproj/error_log.h
+++ b/mach_init.tproj/error_log.h
@@ -31,7 +31,9 @@
 
 #import <mach/mach.h>
 
-extern void init_errlog(boolean_t is_init);
+extern void init_errlog(boolean_t);
+extern void stop_errlog(void);
+extern void close_errlog(void);
 extern void debug(const char *format, ...);
 extern void info(const char *format, ...);
 extern void log(const char *format, ...);
@@ -42,5 +44,4 @@ extern void unix_error(const char *msg, ...);
 extern void fatal(const char *msg, ...);
 extern void kern_fatal(kern_return_t result, const char *msg, ...);
 extern void unix_fatal(const char *msg, ...);
-extern void close_errlog(void);
 
diff --git a/mach_init.tproj/initConf b/mach_init.tproj/initConf
deleted file mode 100644
index b52c7e9..0000000
--- a/mach_init.tproj/initConf
+++ /dev/null
@@ -1,7 +0,0 @@
-services FreeService1 FreeService2 EnvironService=1;
-init testServer services Service=2 TerminalService;
-# server "/NextApps/Terminal -Lines 24 -Columns 60" services TerminalService;
-server "/NextApps/Shell" services ShellService;
-machports 0=NetMsgService=0 3=WindowService=3;
-
-
diff --git a/mach_init.tproj/lists.c b/mach_init.tproj/lists.c
index 9f371a1..ee1a008 100644
--- a/mach_init.tproj/lists.c
+++ b/mach_init.tproj/lists.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -62,6 +62,7 @@ unsigned nservices;		/* number of services in list */
 void
 init_lists(void)
 {
+	bootstraps.ref_count = 2; /* make sure we never deallocate this one */
 	bootstraps.next = bootstraps.prev = &bootstraps;
 	servers.next = servers.prev = &servers;
 	services.next = services.prev = &services;
@@ -70,13 +71,14 @@ init_lists(void)
 
 server_t *
 new_server(
-	servertype_t	servertype,
-	const char	*cmd,
-	int		priority)
+	bootstrap_info_t	*bootstrap,
+	const char		*cmd,
+	int			uid,
+	servertype_t		servertype)
 {
 	server_t *serverp;
 
-	debug("adding new server \"%s\" with priority %d\n", cmd, priority);	
+	debug("adding new server \"%s\" with uid %d\n", cmd, uid);	
 	serverp = NEW(server_t, 1);
 	if (serverp != NULL) {
 		/* Doubly linked list */
@@ -85,15 +87,23 @@ new_server(
 		serverp->next = &servers;
 		servers.prev = serverp;
 
+		bootstrap->ref_count++;
+		serverp->bootstrap = bootstrap;
+
+		serverp->pid = NO_PID;
+		serverp->task_port = MACH_PORT_NULL;
+		serverp->uid = uid;
+
 		serverp->port = MACH_PORT_NULL;
 		serverp->servertype = servertype;
-		serverp->priority = priority;
+		serverp->activity = 0;
+		serverp->active_services = 0;
 		strncpy(serverp->cmd, cmd, sizeof serverp->cmd);
 		LAST_ELEMENT(serverp->cmd) = '\0';
 	}
 	return serverp;
 }
-			
+	
 service_t *
 new_service(
 	bootstrap_info_t	*bootstrap,
@@ -103,10 +113,7 @@ new_service(
 	servicetype_t	servicetype,
 	server_t	*serverp)
 {
-	extern mach_port_t notify_port;
         service_t *servicep;
-	mach_port_t pport;
-        kern_return_t result;
         
 	servicep = NEW(service_t, 1);
 	if (servicep != NULL) {
@@ -120,23 +127,11 @@ new_service(
 		
 		strncpy(servicep->name, name, sizeof servicep->name);
 		LAST_ELEMENT(servicep->name) = '\0';
+		servicep->servicetype = servicetype;
 		servicep->bootstrap = bootstrap;
-		servicep->server = serverp;
 		servicep->port = service_port;
-                result = mach_port_request_notification(mach_task_self(),
-                                                        service_port,
-                                                        MACH_NOTIFY_DEAD_NAME,
-                                                        0,
-                                                        notify_port,
-                                                        MACH_MSG_TYPE_MAKE_SEND_ONCE,
-                                                        &pport);
-                if (result == KERN_SUCCESS) {
-                    debug("added notification for %s\n", servicep->name);
-                } else {
-                    error("couldn't add notification for %s: %s\n", servicep->name, mach_error_string(result));
-                }
-                servicep->isActive = isActive;
-		servicep->servicetype = servicetype;
+		servicep->server = serverp;
+		servicep->isActive = isActive;
 	}
 	return servicep;
 }
@@ -147,10 +142,7 @@ new_bootstrap(
 	mach_port_t	bootstrap_port,
 	mach_port_t	requestor_port)
 {
-	extern mach_port_t notify_port;
 	bootstrap_info_t *bootstrap;
-	mach_port_t pport;
-	kern_return_t result;
 
 	bootstrap = NEW(bootstrap_info_t, 1);
 	if (bootstrap != NULL) {
@@ -162,19 +154,10 @@ new_bootstrap(
 		
 		bootstrap->bootstrap_port = bootstrap_port;
 		bootstrap->requestor_port = requestor_port;
-		bootstrap->parent = parent;
-                result = mach_port_request_notification(mach_task_self(),
-                                                        requestor_port,
-                                                        MACH_NOTIFY_DEAD_NAME,
-                                                        0,
-                                                        notify_port,
-                                                        MACH_MSG_TYPE_MAKE_SEND_ONCE, &pport); 
-                if (result == KERN_SUCCESS) {
-                    info("added notification for sub-bootstrap");
-                } else {
-                    error("couldn't add notification for sub-bootstrap: %s\n", mach_error_string(result));
-                }
 
+		bootstrap->ref_count = 1;
+		bootstrap->parent = parent;
+		parent->ref_count++;
 	}
 	return bootstrap;
 }
@@ -183,20 +166,28 @@ bootstrap_info_t *
 lookup_bootstrap_by_port(mach_port_t port)
 {
 	bootstrap_info_t *bootstrap;
+	bootstrap_info_t *first;
+	server_t *serverp;
 
-	for (  bootstrap = FIRST(bootstraps)
-	     ; !IS_END(bootstrap, bootstraps)
-	     ; bootstrap = NEXT(bootstrap))
-	{
+	bootstrap = first = FIRST(bootstraps);
+	do {  
 		if (bootstrap->bootstrap_port == port)
 			return bootstrap;
+		bootstrap = NEXT(bootstrap);
+	} while (bootstrap != first);
+	
+	for (  serverp = FIRST(servers)
+	     ; !IS_END(serverp, servers)
+	     ; serverp = NEXT(serverp))
+	{
+	  	if (port == serverp->port)
+			return serverp->bootstrap;
 	}
-
-	return &bootstraps;
+	return NULL;
 }
 
 bootstrap_info_t *
-lookup_bootstrap_req_by_port(mach_port_t port)
+lookup_bootstrap_by_req_port(mach_port_t port)
 {
 	bootstrap_info_t *bootstrap;
 
@@ -247,13 +238,32 @@ void
 delete_service(service_t *servicep)
 {
 	unlink_service(servicep);
+	switch (servicep->servicetype) {
+	case REGISTERED:
+		info("Registered service %s deleted", servicep->name);
+		mach_port_deallocate(mach_task_self(), servicep->port);
+		break;
+	case DECLARED:
+		info("Declared service %s now unavailable", servicep->name);
+		mach_port_deallocate(mach_task_self(), servicep->port);
+		mach_port_mod_refs(mach_task_self(), servicep->port,
+				   MACH_PORT_RIGHT_RECEIVE, -1);
+		break;
+	case SELF:
+		error("Self service %s now unavailable", servicep->name);
+		break;
+	default:
+		error("unknown service type %d\n", servicep->servicetype);
+		break;
+	}
 	free(servicep);
 	nservices -= 1;
 }
 
 void
-destroy_services(bootstrap_info_t *bootstrap)
+delete_bootstrap_services(bootstrap_info_t *bootstrap)
 {
+	server_t  *serverp;
 	service_t *servicep;
 	service_t *next;
 	
@@ -264,24 +274,17 @@ destroy_services(bootstrap_info_t *bootstrap)
 		next = NEXT(servicep);
 	  	if (bootstrap != servicep->bootstrap)
 			continue;
-		unlink_service(servicep);
-		switch (servicep->servicetype) {
-		case REGISTERED:
-			log("Service %s deleted - bootstrap deleted", servicep->name);
-			msg_destroy_port(servicep->port);
-			delete_service(servicep);
-			break;
-		case DECLARED:	// don't alter status of (now unavailable) server
-			error("Declared service %s now unavailable", servicep->name);
+
+		if (!servicep->isActive || !servicep->server) {
 			delete_service(servicep);
-			break;
-		case SELF:
-			error("Self service %s now unavailable", servicep->name);
-			break;
-		default:
-			error("unknown service type %d\n", servicep->servicetype);
-			break;
+			continue;
 		}
+
+		serverp = servicep->server;
+		delete_service(servicep);
+		serverp->active_services--;
+		if (!active_server(serverp))
+			delete_server(serverp);
 	}
 }
 
@@ -300,6 +303,21 @@ lookup_service_by_port(mach_port_t port)
         return NULL;
 }
 
+service_t *
+lookup_service_by_server(server_t *serverp)
+{
+	service_t *servicep;
+	
+        for (  servicep = FIRST(services)
+	     ; !IS_END(servicep, services)
+	     ; servicep = NEXT(servicep))
+	{
+	  	if (serverp == servicep->server)
+			return servicep;
+	}
+        return NULL;
+}
+
 server_t *
 lookup_server_by_task_port(mach_port_t port)
 {
@@ -315,33 +333,6 @@ lookup_server_by_task_port(mach_port_t port)
 	return NULL;
 }
 
-void
-delete_bootstrap(bootstrap_info_t *bootstrap)
-{
-	bootstrap_info_t *child_bootstrap;
-
-	ASSERT(bootstrap->prev->next == bootstrap);
-	ASSERT(bootstrap->next->prev == bootstrap);
-
-	destroy_services(bootstrap);
-	for (  child_bootstrap = FIRST(bootstraps)
-	     ; !IS_END(child_bootstrap, bootstraps)
-	     ; child_bootstrap = NEXT(child_bootstrap))
-	{
-		if (child_bootstrap->parent == bootstrap)
-			delete_bootstrap(child_bootstrap);
-	}
-
-	debug("deleting bootstrap %d, requestor %d",
-		bootstrap->bootstrap_port,
-		bootstrap->requestor_port);
-	bootstrap->prev->next = bootstrap->next;
-	bootstrap->next->prev = bootstrap->prev;
-	mach_port_destroy(mach_task_self(), bootstrap->bootstrap_port);
-	mach_port_deallocate(mach_task_self(), bootstrap->requestor_port);
-	free(bootstrap);
-}
-
 server_t *
 lookup_server_by_port(mach_port_t port)
 {
@@ -357,19 +348,135 @@ lookup_server_by_port(mach_port_t port)
 	return NULL;
 }
 
-server_t *
-find_init_server(void)
+void
+delete_server(server_t *serverp)
 {
-	server_t *serverp;
-	
-	for (  serverp = FIRST(servers)
-	     ; !IS_END(serverp, servers)
-	     ; serverp = NEXT(serverp))
+	service_t *servicep;
+	service_t *next;
+
+	info("Deleting server %s", serverp->cmd);
+	ASSERT(serverp->prev->next == serverp);
+	ASSERT(serverp->next->prev == serverp);
+	serverp->prev->next = serverp->next;
+	serverp->next->prev = serverp->prev;
+
+	for (  servicep = FIRST(services)
+	     ; !IS_END(servicep, services)
+	     ; servicep = next)
 	{
-	 	if (serverp->servertype == ETCINIT)
-			return serverp;
+		next = NEXT(servicep);
+	  	if (serverp == servicep->server)
+			delete_service(servicep);
 	}
-	return NULL;
+
+	deallocate_bootstrap(serverp->bootstrap);
+
+#ifndef DELAYED_BOOTSTRAP_DESTROY
+	if (serverp->port)
+		mach_port_mod_refs(mach_task_self(), serverp->port,
+				   MACH_PORT_RIGHT_RECEIVE, -1);
+#endif	
+
+	free(serverp);
+}	
+
+void
+deactivate_bootstrap(bootstrap_info_t *bootstrap)
+{
+	bootstrap_info_t *deactivating_bootstraps;
+	bootstrap_info_t *query_bootstrap;
+	bootstrap_info_t *next_limit;
+	bootstrap_info_t *limit;
+
+	/*
+	 * we need to recursively deactivate the whole subset tree below
+	 * this point.  But we don't want to do real recursion because
+	 * we don't have a limit on the depth.  So, build up a chain of
+	 * active bootstraps anywhere underneath this one.
+	 */
+	deactivating_bootstraps = bootstrap;
+	bootstrap->deactivate = NULL;
+	for (next_limit = deactivating_bootstraps, limit = NULL
+			 ; deactivating_bootstraps != limit
+			 ; limit = next_limit, next_limit = deactivating_bootstraps)
+	{
+		for (bootstrap = deactivating_bootstraps
+				 ; bootstrap != limit
+				 ; bootstrap = bootstrap->deactivate)
+		{
+			for (  query_bootstrap = FIRST(bootstraps)
+				   ; !IS_END(query_bootstrap, bootstraps)
+				   ; query_bootstrap = NEXT(query_bootstrap))
+			{
+				if (query_bootstrap->parent == bootstrap &&
+					query_bootstrap->requestor_port != MACH_PORT_NULL) {
+					mach_port_deallocate(
+										 mach_task_self(),
+										 query_bootstrap->requestor_port);
+					query_bootstrap->requestor_port = MACH_PORT_NULL;
+					query_bootstrap->deactivate = deactivating_bootstraps;
+					deactivating_bootstraps = query_bootstrap;
+				}
+			}
+		}
+	}
+
+	/*
+	 * The list is ordered with the furthest away progeny being
+	 * at the front, and concluding with the one we started with.
+	 * This allows us to safely deactivate and remove the reference
+	 * each holds on their parent without fear of the chain getting
+	 * corrupted (because each active parent holds a reference on
+	 * itself and that doesn't get removed until we reach its spot
+	 * in the list).
+	 */
+	do {
+		bootstrap = deactivating_bootstraps;
+		deactivating_bootstraps = bootstrap->deactivate;
+
+		info("deactivating bootstrap %x", bootstrap->bootstrap_port);
+
+		delete_bootstrap_services(bootstrap);
+		
+		mach_port_deallocate(mach_task_self(), bootstrap->bootstrap_port);
+
+#ifdef DELAYED_BOOTSTRAP_DESTROY
+		{
+			mach_port_t previous;
+			mach_port_request_notification(
+					mach_task_self(),
+					bootstrap->bootstrap_port,
+					MACH_NOTIFY_NO_SENDERS,
+					1,
+					bootstrap->bootstrap_port,
+					MACH_MSG_TYPE_MAKE_SEND_ONCE,
+					&previous);
+		}
+#else
+		mach_port_mod_refs(
+					mach_task_self(),
+					bootstrap->bootstrap_port,
+					MACH_PORT_RIGHT_RECEIVE,
+					-1);
+		bootstrap->bootstrap_port = MACH_PORT_NULL;
+		deallocate_bootstrap(bootstrap);
+#endif
+
+	} while (deactivating_bootstraps != NULL);
+}
+
+void
+deallocate_bootstrap(bootstrap_info_t *bootstrap)
+{
+	ASSERT(bootstrap->prev->next == bootstrap);
+	ASSERT(bootstrap->next->prev == bootstrap);
+	if (--bootstrap->ref_count > 0)
+		return;
+
+	bootstrap->prev->next = bootstrap->next;
+	bootstrap->next->prev = bootstrap->prev;
+	deallocate_bootstrap(bootstrap->parent);
+	free(bootstrap);
 }
 
 void *
diff --git a/mach_init.tproj/lists.h b/mach_init.tproj/lists.h
index 99e5478..4ad1515 100644
--- a/mach_init.tproj/lists.h
+++ b/mach_init.tproj/lists.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -29,6 +29,7 @@
  * lists.h -- interface to list routines
  */
 
+#import <sys/types.h>
 #import <mach/mach.h>
 #import <mach/boolean.h>
 #import <servers/bootstrap_defs.h>
@@ -46,8 +47,10 @@ struct bootstrap {
 	bootstrap_info_t		*next;		/* list of all bootstraps */
 	bootstrap_info_t		*prev;
 	bootstrap_info_t		*parent;
+	bootstrap_info_t		*deactivate;	/* list being deactivated */
 	mach_port_name_t		bootstrap_port;
 	mach_port_name_t		requestor_port;
+	unsigned int			ref_count;
 };
 
 /* Service types */
@@ -74,8 +77,8 @@ struct service {
 typedef enum {
 	SERVER,		/* Launchable server */
 	RESTARTABLE,	/* Restartable server */
-	ETCINIT,	/* Special processing for /etc/init */
-	MACHINIT	/* mach_init doesn't get launched. */
+	DEMAND,		/* Restartable server - on demand */
+	MACHINIT,	/* mach_init doesn't get launched. */
 } servertype_t;
 
 #define	NULL_SERVER	NULL
@@ -86,25 +89,33 @@ struct server {
 	server_t	*prev;
 	servertype_t	servertype;
 	cmd_t		cmd;		/* server command to exec */
-	int		priority;	/* priority to give server */
+	int			uid;		/* uid to exec server with */
 	mach_port_t	port;		/* server's priv bootstrap port */
-	mach_port_name_t	task_port;	/* server's task port */
+	mach_port_t	task_port;	/* server's task port */
+	pid_t		pid;		/* server's pid */
+	int		activity;		/* count of checkins/registers this instance */
+	int		active_services;/* count of active services */
+	bootstrap_info_t *bootstrap; /* bootstrap context */
 };
 
 #define	NO_PID	(-1)
 
 extern void init_lists(void);
+
 extern server_t *new_server(
-	servertype_t	servertype,
-	const char	*cmd,
-	int		priority);
-extern service_t *new_service(
+	bootstrap_info_t 	*bootstrap,
+	const char			*cmd,
+	int					uid,
+	servertype_t		servertype);
+
+extern service_t 		*new_service(
 	bootstrap_info_t	*bootstrap,
-	const char	*name,
-	mach_port_t		service_port,
-	boolean_t	isActive,
-	servicetype_t	servicetype,
-	server_t	*serverp);
+	const char			*name,
+	mach_port_t			service_port,
+	boolean_t			isActive,
+	servicetype_t		servicetype,
+	server_t			*serverp);
+
 extern bootstrap_info_t *new_bootstrap(
 	bootstrap_info_t	*parent,
 	mach_port_name_t	bootstrap_port,
@@ -112,13 +123,22 @@ extern bootstrap_info_t *new_bootstrap(
 
 extern server_t *lookup_server_by_port(mach_port_t port);
 extern server_t *lookup_server_by_task_port(mach_port_t port);
-extern bootstrap_info_t *lookup_bootstrap_by_port(mach_port_t port);
-extern bootstrap_info_t *lookup_bootstrap_req_by_port(mach_port_t port);
+extern void setup_server(server_t *serverp);
+extern void delete_server(server_t *serverp);
+extern boolean_t active_server(server_t *serverp);
+extern boolean_t useless_server(server_t *serverp);
+
+extern void delete_service(service_t *servicep);
 extern service_t *lookup_service_by_name(bootstrap_info_t *bootstrap, name_t name);
 extern service_t *lookup_service_by_port(mach_port_t port);
-extern server_t *find_init_server(void);
-extern void delete_service(service_t *servicep);
-extern void delete_bootstrap(bootstrap_info_t *bootstrap);
+extern service_t *lookup_service_by_server(server_t *serverp);
+
+extern bootstrap_info_t *lookup_bootstrap_by_port(mach_port_t port);
+extern bootstrap_info_t *lookup_bootstrap_by_req_port(mach_port_t port);
+extern void deactivate_bootstrap(bootstrap_info_t *bootstrap);
+extern void deallocate_bootstrap(bootstrap_info_t *bootstrap);
+extern boolean_t active_bootstrap(bootstrap_info_t *bootstrap);
+
 extern void *ckmalloc(unsigned nbytes);
 
 extern bootstrap_info_t bootstraps;		/* head of list of bootstrap ports */
diff --git a/mach_init.tproj/mach_init.8 b/mach_init.tproj/mach_init.8
new file mode 100644
index 0000000..84694cd
--- /dev/null
+++ b/mach_init.tproj/mach_init.8
@@ -0,0 +1,100 @@
+.\" Copyright (c) 2002, Apple Computer, Inc.  All rights reserved.
+.\"
+.Dd March 20, 2002
+.Dt MACH_INIT 8
+.Os "Mac OS X"
+.Sh NAME
+.Nm mach_init
+.Nd Mach service naming (bootstrap) daemon
+.Sh SYNOPSIS
+.Nm mach_init
+.Op Fl D
+.Op Fl d
+.Op Fl F
+.Op Fl r Ar name-in-existing-server
+.Sh DESCRIPTION
+.Nm mach_init
+is a daemon that maintains various mappings between service names and
+the Mach ports that provide access to those services.  Clients of mach_init
+can register and lookup services, create new mapping subsets, and
+associate services with declared servers.  The mach_init daemon will
+also be responsible for launching (and/or re-launching) those service
+providing servers when attempts to use one or more of the associated services
+is detected.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl D
+When the
+.Fl D
+option is specified,
+.Nm mach_init
+starts in normal (non-debug) mode.  This is the default.
+.It Fl d
+When the
+.Fl d
+option is specified,
+.Nm mach_init
+starts in debug mode.
+.It Fl F
+When the
+.Fl F
+option is specified,
+.Nm mach_init
+forks during initialization so that it doesn't have to be put in
+the background manually by the caller.
+.It Fl r
+Using the
+.Fl r
+option tells
+.Nm mach_init
+to register itself in a previously running copy of
+.Nm mach_init
+under the service name
+.Ar name-in-existing-server.
+This is most useful when debugging new instances of
+.Nm mach_init
+itself, but can also be used for robustness or to allow the subsequent
+.Nm mach_init
+processes to run as a non-root user.  As mach_init is often used to
+launch servers, this could be more secure.  However, 
+.Nm mach_init
+will not allow a server declaration to specify a user id different
+than that of the requesting client (unless the client is running as root).
+So it shouldn't be required for a secure configuration.
+.El
+.Pp
+Access to
+.Nm mach_init 
+is provided through the bootstrap series of RPC APIs
+over service ports published by mach_init itself. Each Mach task has
+an assigned bootstrap port retrieved via task_get_bootstrap_port().
+These bootstrap port registrations are inherited across fork().
+.Pp
+The service registrations are grouped into subsets, providing a level
+of security. Only processes with access to the subset's bootstrap port
+will be able to register/lookup Mach ports within that subset.  Lookups
+from within a subset will search the subset first, then move on to its
+parent, and then its grand-parent, etc... until a string name match is
+found or the top of the bootstrap tree is reached.  Subsets are sometimes
+associated with login sessions to protect session-specific ports from being
+exposed outside the session.
+.Pp
+The first instance of
+.Nm mach_init
+is responsible for launching the traditional BSD process control initialization
+daemon (/sbin/init).
+.Sh SAMPLE USAGE
+.Pp
+mach_init -d -r com.company.bootstrap
+.Pp
+.Nm mach_init
+will start in debug mode, and register itself in an already running
+instance of
+.Nm mach_init
+under the service name com.company.bootstrap.
+.Sh NOTE
+.Pp
+Sending a SIGHUP to a running mach_init will toggle debug mode.
+.Sh SEE ALSO
+.Xr init 8
diff --git a/mach_init.tproj/parser.c b/mach_init.tproj/parser.c
deleted file mode 100644
index e20f194..0000000
--- a/mach_init.tproj/parser.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990.  All rights reserved.
- *
- * parser.c -- configuration file parser
- */
-#import	<mach/boolean.h>
-#import <mach/port.h>
-
-#import	<string.h>
-#import <libc.h>
-#import	<ctype.h>
-#import <stdio.h>
-
-#import "lists.h"
-#import "bootstrap_internal.h"
-#import "error_log.h"
-#import "parser.h"
-
-
-#ifndef ASSERT
-#define ASSERT(p)
-#endif
-
-#define	MAX_TOKEN_LEN	128
-
-#define	NELEM(x)			(sizeof(x)/sizeof((x)[0]))
-#define	LAST_ELEMENT(x)		((x)[NELEM(x)-1])
-#define	STREQ(a, b)			(strcmp(a, b) == 0)
-#define	NEW(type, num)		((type *)ckmalloc(sizeof(type) * (num)))
-
-typedef enum {
-	ASSIGN_TKN, EOF_TKN, FORWARD_TKN, INIT_TKN, NUM_TKN,
-	RESTARTABLE_TKN, SELF_TKN, SEMICOLON_TKN, SERVER_TKN, SERVICES_TKN,
-	STRING_TKN, ERROR_TKN, PRI_TKN
-} token_t;
-
-typedef struct {
-	char *string;
-	token_t token;
-} keyword_t;
-
-static keyword_t keywords[] = {
-	{ "forward",			FORWARD_TKN },
-	{ "init",			INIT_TKN },
-	{ "priority",			PRI_TKN },
-	{ "restartable",		RESTARTABLE_TKN },
-	{ "self",			SELF_TKN },
-	{ "server",			SERVER_TKN },
-	{ "services",			SERVICES_TKN },
-	{ NULL,				ERROR_TKN }
-};
-
-static FILE *conf;
-static int (*charget)(void);
-static const char *default_conf_ptr;
-
-static char token_string[MAX_TOKEN_LEN];
-static token_t current_token;
-static int token_num;
-static int token_priority;
-static int peekc;
-
-static int get_from_conf(void);
-static int get_from_default(void);
-static boolean_t parse_conf_file(void);
-static boolean_t parse_self(void);
-static boolean_t parse_server(void);
-static boolean_t parse_service(server_t *serverp);
-static boolean_t parse_pri(void);
-static void advance_token(void);
-static token_t keyword_lookup(void);
-
-/*
- * init_config -- read configuration file and build-up initial server and
- * service lists
- *
- * If can't find a suitable bootstrap.conf, use configuration given in
- * bootstrap.c to get system booted so someone can correct bootstrap.conf
- */
-void
-init_config(void)
-{
-	boolean_t parse_ok;
-
-	conf = fopen(conf_file, "r");
-	if (conf != NULL)
-		charget = get_from_conf;
-	else {
-		error("Can't open %s -- using default configuration", conf_file);
-		charget = get_from_default;
-	}
-	
-	parse_ok = parse_conf_file();
-	if ( ! parse_ok && charget == get_from_conf) {
-		error("Can't parse %s -- using default configuration", conf_file);
-		charget = get_from_default;
-		init_lists();
-		peekc = 0;
-		parse_ok = parse_conf_file();
-	}
-	if ( ! parse_ok )
-		fatal("Can't parse default configuration file");
-}
-
-/*
- * Function pointer "charget" points at get_from_conf or get_from_default
- */
-static int
-get_from_conf(void)
-{
-	return getc(conf);
-}
-
-static int
-get_from_default(void)
-{
-	int c;
-	
-	if (default_conf_ptr == NULL)
-		default_conf_ptr = default_conf;
-		
-	if (c = *default_conf_ptr)
-		default_conf_ptr++;
-	if (c == '\0')
-		c = EOF;
-	return c;
-}
-
-/*
- * What follows is a simple recursive descent parser
- * ("we don't need no stinkin' yacc")
- */
-static boolean_t
-parse_conf_file(void)
-{
-	boolean_t parse_ok, good_parse;
-	
-	/*
-	 * Configuration file syntax (and parsing routines).
-	 *
-	 * (parse_conf_file)
-	 * CONF_FILE := STMT [ ; STMT ]* [ ; ]
-	 * STMT := SERVER | SERVICE | SELF | forward | initpri
-	 *
-	 * (parse_server)
-	 * SERVER := [ restartable ]  ( server | init ) SERVER_PATH_ARGS [ SERVICE ]
-	 *
-	 * (parse_service)
-	 * SERVICE := services [ SERVICE_DECL ]+
-	 * SERVICE_DECL := SERVICE_NAME
-	 *
-	 * (parse_self)
-	 * SELF := self [ priority = NUM ] SERVICE_DECL
-	 *
-	 * Or more simply, just a list of:
-	 *
-	 * [[restartable] (server|init) SERVER_PATH_ARGS] [ priority = NUM ]
-	 *   [services SERVICE_NAME [ SERVICE_NAME [ = NUM ]]*] ;
-	 *
-	 * self [ SERVICE_NAME ]+
-	 *
-	 * [ forward ]
-	 *
-	 */
-	advance_token();
-	if (current_token == EOF_TKN) {
-		error("Empty configuration file: %s", conf_file);
-		return FALSE;
-	}
-	
-	good_parse = TRUE;
-	while (current_token != EOF_TKN) {
-		parse_ok = TRUE;
-		switch (current_token) {
-		case RESTARTABLE_TKN:
-		case SERVER_TKN:
-		case INIT_TKN:
-			parse_ok = parse_server();
-			break;
-		case SERVICES_TKN:
-			parse_ok = parse_service(NULL);
-			break;
-		case SELF_TKN:
-			parse_ok = parse_self();
-			break;
-		case FORWARD_TKN:
-			forward_ok = TRUE;
-			advance_token();
-			break;
-		case SEMICOLON_TKN:
-			advance_token();
-			break;
-		case EOF_TKN:
-			break;
-		default:
-			parse_error(token_string, "start of new declaration");
-			parse_ok = FALSE;
-			break;
-		}
-		switch (current_token) {
-		case SEMICOLON_TKN:
-			advance_token();
-			break;
-		case EOF_TKN:
-			break;
-		default:
-			if (parse_ok)
-				parse_error(token_string, "expected ';'");
-			/* Try to re-sync with input */
-			while (current_token != SEMICOLON_TKN && current_token != EOF_TKN)
-				advance_token();
-			parse_ok = FALSE;
-			break;
-		}
-		if (! parse_ok)
-			good_parse = FALSE;
-	}
-	return good_parse;
-}
-
-static boolean_t
-parse_self(void)
-{
-	name_t name;
-	
-	ASSERT(current_token == SELF_TKN);
-	advance_token();		/* Skip SELF_TKN */
-	if (current_token == PRI_TKN) {
-		boolean_t ok;
-		ok = parse_pri();
-		if (!ok)
-			return FALSE;
-		init_priority = token_priority;
-	}
-	while (current_token == STRING_TKN) {
-		if (strlen(token_string) >= sizeof(name_t)) {
-			parse_error(token_string, "Service name too long");
-			return FALSE;
-		}
-		if (lookup_service_by_name(&bootstraps, token_string) != NULL)
-		{
-			parse_error(token_string, "Service name previously declared");
-			return FALSE;
-		}
-		strcpy(name, token_string);
-		advance_token();
-		(void) new_service(&bootstraps, name, MACH_PORT_NULL, ACTIVE, SELF,
-				   NULL_SERVER);
-	}
-	return TRUE;
-}
-
-static boolean_t
-parse_server(void)
-{
-	server_t *serverp;
-	servertype_t servertype = SERVER;
-	
-	if (current_token == RESTARTABLE_TKN) {
-		advance_token();
-		servertype = RESTARTABLE;
-	}
-	switch (current_token) {
-	case SERVER_TKN:
-		advance_token();
-		break;
-	case INIT_TKN:
-		if (find_init_server() != NULL) {
-			parse_error(token_string,
-				"Can't specify multiple init servers");
-			return FALSE;
-		}
-		if (servertype == RESTARTABLE) {
-			parse_error(token_string,
-				"Init server can not be restartable");
-		 	return FALSE;
-		}
-		servertype = ETCINIT;
-		advance_token();
-		break;
-	default:
-		parse_error(token_string, "expected \"server\" or \"init\"");
-		return FALSE;
-	}
-	if (current_token == PRI_TKN) {
-		boolean_t ok;
-		ok = parse_pri();
-		if (!ok)
-			return FALSE;
-	} else
-		token_priority = BASEPRI_USER;
-	if (current_token != STRING_TKN) {
-		parse_error(token_string,
-			    "expected string giving server to exec");
-		return FALSE;
-	}
-	serverp = new_server(servertype, token_string, token_priority);
-	advance_token();
-	if (current_token == SERVICES_TKN)
-		return parse_service(serverp);
-	return TRUE;
-}
-
-static boolean_t
-parse_service(server_t *serverp)
-{
-	name_t name;
-	
-	ASSERT(current_token == SERVICES_TKN);
-	advance_token();		/* Skip SERVICES_TKN */
-	while (current_token == STRING_TKN) {
-		if (strlen(token_string) >= sizeof(name_t)) {
-			parse_error(token_string, "Service name too long");
-			return FALSE;
-		}
-		if (lookup_service_by_name(&bootstraps, token_string) != NULL)
-		{
-			parse_error(token_string, "Service name previously declared");
-			return FALSE;
-		}
-		strcpy(name, token_string);
-		advance_token();
-		(void) new_service(&bootstraps, name, MACH_PORT_NULL, !ACTIVE,
-				   DECLARED, serverp);
-	}
-	return TRUE;
-}
-
-/*
- * Parse priority=NUM
- */
-static boolean_t
-parse_pri(void)
-{
-	ASSERT(current_token == PRI_TKN);
-	advance_token();		/* Skip PRI_TKN */
-	if (current_token != ASSIGN_TKN) {
-		parse_error(token_string, "expected '='");
-		return FALSE;
-	}
-	advance_token();		/* Skip = */
-	if (current_token != NUM_TKN) {
-		parse_error(token_string, "expected NUM");
-		return FALSE;
-	}
-	advance_token();		/* Skip NUM */
-	token_priority = token_num;
-	return TRUE;
-}
-/*
- * advance_token -- advances input to next token
- *	Anything from a '#' on is comment and ignored
- *	
- * On return:
- *		current_token contains token_t of next token
- *		token_string contains string value of next token
- *		if token was number, token_num contains numeric value of token
- */
-static void
-advance_token(void)
-{
-	char *cp;
-
-again:	
-	while (peekc == '\0' || isspace(peekc))
-		peekc = (*charget)();
-	
-	/* Skip comments */
-	if (peekc == '#') {
-		while (peekc != EOF && peekc != '\n')
-			peekc = (*charget)();
-		goto again;
-	}
-	
-	cp = token_string;
-	*cp = '\0';
-	
-	if (peekc == EOF) {
-		current_token = EOF_TKN;
-		return;
-	}
-
-	if (isalpha(peekc) || peekc == '\\') {
-		/*
-		 * this only allows names to be alphanumerics, '_', and
-		 * backslash escaped characters.
-		 * If you want something fancier, use "..."
-		 */
-		current_token = STRING_TKN;	/* guarantee it's not ERROR_TKN */
-		for (; isalnum(peekc) || peekc == '_' || peekc == '\\';
-		 peekc = (*charget)()) {
-			if (cp >= &LAST_ELEMENT(token_string)) {
-				cp = token_string;
-				parse_error(token_string, "token too long");
-				current_token = ERROR_TKN;
-			}
-			if (peekc == '\\')
-				peekc = (*charget)();
-			*cp++ = peekc;
-		}
-		*cp = '\0';
-		if (current_token != ERROR_TKN)
-			current_token = keyword_lookup();
-		return;
-	}
-	
-	/* Handle "-quoted strings */
-	if (peekc == '"') {
-		peekc = (*charget)();
-		for (; peekc != EOF && peekc != '"'; peekc = (*charget)()) {
-			if (cp >= &LAST_ELEMENT(token_string)) {
-				cp = token_string;
-				parse_error(token_string, "token too long");
-				current_token = ERROR_TKN;
-			}
-			if (peekc == '\\')
-				peekc = (*charget)();
-			if (peekc == '\n') {
-				cp = token_string;
-				parse_error(token_string, "Missing \"");
-				current_token = ERROR_TKN;
-			}
-			*cp++ = peekc;
-		}
-		if (peekc == EOF) {
-			cp = token_string;
-			parse_error(token_string, "Missing \"");
-			current_token = ERROR_TKN;
-		} else
-			peekc = (*charget)();	/* skip closing " */
-		*cp = '\0';
-		if (current_token != ERROR_TKN)
-			current_token = STRING_TKN;
-		return;
-	}
-
-	if (isdigit(peekc)) {
-		for (token_num = 0; isdigit(peekc); peekc = (*charget)())
-			token_num = token_num * 10 + peekc - '0';
-		current_token = NUM_TKN;
-		return;
-	}
-	
-	if (peekc == ';') {
-		peekc = (*charget)();
-		current_token = SEMICOLON_TKN;
-		return;
-	}
-	
-	if (peekc == '=') {
-		peekc = (*charget)();
-		current_token = ASSIGN_TKN;
-		return;
-	}
-	
-	current_token = ERROR_TKN;
-	return;
-}	
-
-static token_t
-keyword_lookup(void)
-{
-	keyword_t *kwp;
-	
-	for (kwp = keywords; kwp->string; kwp++)
-		if (STREQ(kwp->string, token_string))
-			return kwp->token;
-	return STRING_TKN;
-}
-
diff --git a/mach_init.tproj/parser.h b/mach_init.tproj/parser.h
deleted file mode 100644
index 079ec7b..0000000
--- a/mach_init.tproj/parser.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * bootstrap -- fundamental service initiator and port server
- * Mike DeMoney, NeXT, Inc.
- * Copyright, 1990.  All rights reserved.
- *
- * parser.h -- interface to configuration file parser
- */
-#import "lists.h"
-
-extern void init_config(void);
-
-
diff --git a/mach_init.tproj/rpc_services.c b/mach_init.tproj/rpc_services.c
index 6c08bbe..193e180 100644
--- a/mach_init.tproj/rpc_services.c
+++ b/mach_init.tproj/rpc_services.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -45,8 +45,109 @@
 #define	NULL	((void *)0)
 #endif NULL
  
+#define bsstatus(servicep) \
+	(((servicep)->isActive) ? BOOTSTRAP_STATUS_ACTIVE : \
+	 (((servicep)->server && (servicep)->server->servertype == DEMAND) ? \
+		BOOTSTRAP_STATUS_ON_DEMAND : BOOTSTRAP_STATUS_INACTIVE))
+
 /* extern port_all_t backup_port; */
 
+/*
+ * kern_return_t
+ * bootstrap_create_server(mach_port_t bootstrap_port,
+ *	 cmd_t server_cmd,
+ *	 integer_t server_uid,
+ *	 boolean_t on_demand,
+ *	 mach_port_t *server_portp)
+ *
+ * Returns send rights to server_port of service.  At this point, the
+ * server appears active, so nothing will try to launch it.  The server_port
+ * can be used to delare services associated with this server by calling
+ * bootstrap_create_service() and passing server_port as the bootstrap port.
+ *
+ * Errors:	Returns appropriate kernel errors on rpc failure.
+ *		Returns BOOTSTRAP_NOT_PRIVILEGED, if bootstrap port invalid.
+ */
+kern_return_t
+x_bootstrap_create_server(
+	mach_port_t bootstrap_port,
+	cmd_t server_cmd,
+	int server_uid,
+	boolean_t on_demand,
+	security_token_t sectoken,
+	mach_port_t *server_portp)
+{
+	server_t *serverp;
+	bootstrap_info_t *bootstrap;
+
+	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
+	debug("Server create attempt: \"%s\" bootstrap %x",
+	      server_cmd, bootstrap_port);
+
+	/* No forwarding allowed for this call - security risk (we run as root) */
+	if (!bootstrap || !active_bootstrap(bootstrap)) {
+		debug("Server create: \"%s\": invalid bootstrap %x",
+			server_cmd, bootstrap_port);
+		return BOOTSTRAP_NOT_PRIVILEGED;
+	}
+
+	/* only same uid (or root client) */
+	if (sectoken.val[0] && sectoken.val[0] != server_uid) {
+		log("Server create: \"%s\": invalid security token (%d != %d)",
+			server_cmd, sectoken.val[0], server_uid);
+		return BOOTSTRAP_NOT_PRIVILEGED;
+	}
+	serverp = new_server(
+					bootstrap,
+					server_cmd,
+					server_uid,
+					(on_demand) ? DEMAND : RESTARTABLE);
+	setup_server(serverp);
+
+	info("New server %x in bootstrap %x: \"%s\"",
+					serverp->port, bootstrap_port, server_cmd);
+	*server_portp = serverp->port;
+	return BOOTSTRAP_SUCCESS;
+}
+
+/*
+ * kern_return_t
+ * bootstrap_unprivileged(mach_port_t bootstrap_port,
+ *			  mach_port_t *unpriv_port)
+ *
+ * Given a bootstrap port, return its unprivileged equivalent.  If
+ * the port is already unprivileged, another reference to the same
+ * port is returned.
+ *
+ * This is most often used by servers, which are launched with their
+ * bootstrap port set to the privileged port for the server, to get
+ * an unprivileged version of the same port for use by its unprivileged
+ * children (or any offspring that it does not want to count as part
+ * of the "server" for mach_init registration and re-launch purposes).
+ */
+kern_return_t
+x_bootstrap_unprivileged(
+	mach_port_t bootstrap_port,
+	mach_port_t *unpriv_portp)
+{
+	bootstrap_info_t *bootstrap;
+
+	debug("Get unprivileged attempt for bootstrap %x", bootstrap_port);
+
+	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
+	if (!bootstrap || !active_bootstrap(bootstrap)) {
+		debug("Get unprivileged: invalid bootstrap %x", bootstrap_port);
+		return BOOTSTRAP_NOT_PRIVILEGED;
+	}
+
+	*unpriv_portp = bootstrap->bootstrap_port;
+
+	debug ("Get unpriv bootstrap %x returned for bootstrap %x",
+	       bootstrap->bootstrap_port, bootstrap_port);
+	return BOOTSTRAP_SUCCESS;
+}
+
+  
 /*
  * kern_return_t
  * bootstrap_check_in(mach_port_t bootstrap_port,
@@ -69,23 +170,26 @@ x_bootstrap_check_in(
 	mach_port_t	*service_portp)
 {
 	kern_return_t result;
+	mach_port_t previous;
 	service_t *servicep;
 	server_t *serverp;
 	bootstrap_info_t *bootstrap;
 
-	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
 	serverp = lookup_server_by_port(bootstrap_port);
-	if (serverp == NULL) {
-		debug("bootstrap_check_in service %s has no server",
-			service_name);
-		return BOOTSTRAP_NOT_PRIVILEGED;
-	}
+	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
+	debug("Service checkin attempt for service %s bootstrap %x",
+	      service_name, bootstrap_port);
+
 	servicep = lookup_service_by_name(bootstrap, service_name);
 	if (servicep == NULL || servicep->port == MACH_PORT_NULL) {
 		debug("bootstrap_check_in service %s unknown%s", service_name,
 			forward_ok ? " forwarding" : "");
-		result = BOOTSTRAP_UNKNOWN_SERVICE;
-		goto forward;
+		return  forward_ok ?
+			bootstrap_check_in(
+					inherited_bootstrap_port,
+					service_name,
+					service_portp) :
+			BOOTSTRAP_UNKNOWN_SERVICE;
 	}
 	if (servicep->server != NULL && servicep->server != serverp) {
 		debug("bootstrap_check_in service %s not privileged",
@@ -98,19 +202,54 @@ x_bootstrap_check_in(
 			service_name);
 		return BOOTSTRAP_SERVICE_ACTIVE;
 	}
-	log("Checkin service %s", service_name);
+	debug("Checkin service %s for bootstrap %x", service_name,
+	      bootstrap->bootstrap_port);
 	ASSERT(servicep->isActive == FALSE);
 	servicep->isActive = TRUE;
+
+	if (servicep->server != NULL_SERVER) {
+		/* registered server - service needs backup */
+		serverp->activity++;
+		serverp->active_services++;
+		result = mach_port_request_notification(
+					mach_task_self(),
+					servicep->port,
+					MACH_NOTIFY_PORT_DESTROYED,
+					0,
+					backup_port,
+					MACH_MSG_TYPE_MAKE_SEND_ONCE,
+					&previous);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_request_notification");
+	} else {
+		/* one time use/created service */
+		servicep->servicetype = REGISTERED;
+		result = mach_port_request_notification(
+					mach_task_self(),
+					servicep->port,
+					MACH_NOTIFY_DEAD_NAME,
+					0,
+					notify_port,
+					MACH_MSG_TYPE_MAKE_SEND_ONCE,
+					&previous);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_request_notification");
+		else if (previous != MACH_PORT_NULL) {
+			debug("deallocating old notification port (%x) for checked in service %x",
+				previous, servicep->port);
+			result = mach_port_deallocate(
+						mach_task_self(),
+						previous);
+			if (result != KERN_SUCCESS)
+				kern_fatal(result, "mach_port_deallocate");
+		}
+	}
+
+	info("Check-in service %x in bootstrap %x: %s",
+	      servicep->port, servicep->bootstrap->bootstrap_port, servicep->name);
+
 	*service_portp = servicep->port;
-	info("Check-in port %d for service %s\n",
-	      servicep->port, servicep->name);
 	return BOOTSTRAP_SUCCESS;
-    forward:
-	return forward_ok
-	 ? bootstrap_check_in(inherited_bootstrap_port,
-			     service_name,
-			     service_portp)
-	 : result;
 }
 
 /*
@@ -139,16 +278,22 @@ x_bootstrap_register(
 	name_t	service_name,
 	mach_port_t	service_port)
 {
+	kern_return_t result;
 	service_t *servicep;
 	server_t *serverp;
 	bootstrap_info_t *bootstrap;
 	mach_port_t old_port;
 
-	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
-	ASSERT(canSend(service_port));
-	debug("Register attempt for service %s port %d",
+	debug("Register attempt for service %s port %x",
 	      service_name, service_port);
 
+	/*
+	 * Validate the bootstrap.
+	 */
+	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
+	if (!bootstrap || !active_bootstrap(bootstrap))
+		return BOOTSTRAP_NOT_PRIVILEGED;
+	  
 	/*
 	 * If this bootstrap port is for a server, or it's an unprivileged
 	 * bootstrap can't register the port.
@@ -158,11 +303,6 @@ x_bootstrap_register(
 	if (servicep && servicep->server && servicep->server != serverp)
 		return BOOTSTRAP_NOT_PRIVILEGED;
 
-	if (serverp)
-		bootstrap_port = bootstrap->bootstrap_port;
-	else if (bootstrap_port != bootstrap->bootstrap_port)
-		return BOOTSTRAP_NOT_PRIVILEGED;
-
 	if (servicep == NULL || servicep->bootstrap != bootstrap) {
 		servicep = new_service(bootstrap,
 				       service_name,
@@ -172,21 +312,68 @@ x_bootstrap_register(
 				       NULL_SERVER);
 		debug("Registered new service %s", service_name);
 	} else {
-            if (servicep->isActive) {
-			debug("Register: service %s already active, port %d",
+		if (servicep->isActive) {
+			debug("Register: service %s already active, port %x",
 		 	      servicep->name, servicep->port);
 			ASSERT(!canReceive(servicep->port));
 			return BOOTSTRAP_SERVICE_ACTIVE;
 		}
-            old_port = servicep->port;
+		old_port = servicep->port;
+		if (servicep->servicetype == DECLARED) {
+			servicep->servicetype = REGISTERED;
+
+			if (servicep->server) {
+				ASSERT(servicep->server == serverp);
+				ASSERT(active_server(serverp));
+				servicep->server = NULL_SERVER;
+				serverp->activity++;
+			}
+
+			result = mach_port_mod_refs(
+					mach_task_self(),
+					old_port,
+					MACH_PORT_RIGHT_RECEIVE, 
+					-1);
+			if (result != KERN_SUCCESS)
+				kern_fatal(result, "mach_port_mod_refs");
+		}
+		result = mach_port_deallocate(
+				mach_task_self(),
+				old_port);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_mod_refs");
+		
 		servicep->port = service_port;
-		msg_destroy_port(old_port);
 		servicep->isActive = TRUE;
-		log("Re-registered inactive service %s", service_name);
+		debug("Re-registered inactive service %x bootstrap %x: %s",
+			servicep->port, servicep->bootstrap->bootstrap_port, service_name);
 	}
-	debug("Registering port %d for service %s\n",
-	      servicep->port,
-	      servicep->name);
+
+	/* detect the new service port going dead */
+	result = mach_port_request_notification(
+			mach_task_self(),
+			service_port,
+			MACH_NOTIFY_DEAD_NAME,
+			0,
+			notify_port,
+			MACH_MSG_TYPE_MAKE_SEND_ONCE,
+			&old_port);
+	if (result != KERN_SUCCESS) {
+		debug("Can't request notification on service %x bootstrap %x: %s",
+		       service_port, servicep->bootstrap->bootstrap_port, "must be dead");
+		delete_service(servicep);
+		return BOOTSTRAP_SUCCESS;
+	} else if (old_port != MACH_PORT_NULL) {
+		debug("deallocating old notification port (%x) for service %x",
+		      old_port, service_port);
+		result = mach_port_deallocate(
+				mach_task_self(),
+				old_port);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_deallocate");
+	}
+	info("Registered service %x bootstrap %x: %s",
+	     servicep->port, servicep->bootstrap->bootstrap_port, servicep->name);
 	return BOOTSTRAP_SUCCESS;
 }
 
@@ -215,35 +402,21 @@ x_bootstrap_look_up(
 	servicep = lookup_service_by_name(bootstrap, service_name);
 	if (servicep == NULL || servicep->port == MACH_PORT_NULL) {
 		if (forward_ok) {
-#if	DEBUG
 			debug("bootstrap_look_up service %s forwarding",
 				service_name);
-#endif	DEBUG
 			return bootstrap_look_up(inherited_bootstrap_port,
 						service_name,
 						service_portp);
 		} else {
-#if	DEBUG
 			debug("bootstrap_look_up service %s unknown",
 				service_name);
-#endif	DEBUG
 			return BOOTSTRAP_UNKNOWN_SERVICE;
 		}
 	}
-	if (!canSend(servicep->port)) {
-		error("Mysterious loss of send rights on port %d, "
-		      "deleting service %s",
-		      servicep->port,
-		      servicep->name);
-		delete_service(servicep);
-		return BOOTSTRAP_UNKNOWN_SERVICE;
-	}
 	*service_portp = servicep->port;
-#if	DEBUG
-	debug("Lookup returns port %d for service %s\n",
+	debug("Lookup returns port %x for service %s",
 	      servicep->port,
 	      servicep->name);
-#endif	DEBUG
 	return BOOTSTRAP_SUCCESS;
 }
 
@@ -296,29 +469,74 @@ x_bootstrap_look_up_array(
 			service_ports[i] = MACH_PORT_NULL;
 		}
 	}
-#if	DEBUG
 	debug("bootstrap_look_up_array returns %d ports", service_names_cnt);
-#endif	DEBUG
 	*service_portsp = service_ports;
 	return BOOTSTRAP_SUCCESS;
 }
 
+/*
+ * kern_return_t
+ * bootstrap_parent(mach_port_t bootstrap_port,
+ *		    mach_port_t *parent_port);
+ *
+ * Given a bootstrap subset port, return the parent bootstrap port.
+ * If the specified bootstrap port is already the root subset,
+ * MACH_PORT_NULL will be returned.
+ *
+ * Errors:
+ *	Returns BOOTSTRAP_NOT_PRIVILEGED if the caller is not running
+ *	with an effective user id of root (as determined by the security
+ *	token in the message trailer).
+ */
+kern_return_t
+x_bootstrap_parent(
+	mach_port_t bootstrap_port,
+	security_token_t sectoken,
+	mach_port_t *parent_port)
+{
+#if 0
+	bootstrap_info_t *bootstrap;
+
+	debug("Parent attempt for bootstrap %x", bootstrap_port);
+
+	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
+	if (!bootstrap || !active_bootstrap(bootstrap)) { 
+		debug("Parent attempt for bootstrap %x: invalid bootstrap",
+		      bootstrap_port);
+		return BOOTSTRAP_NOT_PRIVILEGED;
+	}
+	if (sectoken.val[0]) {
+		log("Bootstrap parent for bootstrap %x: invalid security token (%d)",
+		    bootstrap_port, sectoken.val[0]);
+		return BOOTSTRAP_NOT_PRIVILEGED;
+	}
+	debug("Returning bootstrap parent %x for bootstrap %x",
+	      bootstrap->parent->bootstrap_port, bootstrap_port);
+	*parent_port = bootstrap->parent->bootstrap_port;
+	return BOOTSTRAP_SUCCESS;
+#else
+	debug("bootstrap parent for bootstrap %x: not implemented", 
+	      bootstrap_port);
+	return BOOTSTRAP_NOT_PRIVILEGED;
+#endif
+}
+
 /*
  * kern_return_t
  * bootstrap_status(mach_port_t bootstrap_port,
  *	name_t service_name,
- *	boolean_t *service_active);
+ *	bootstrap_status_t *service_active);
  *
- * Returns: service_active is true if service is available.
+ * Returns: service_active indicates if service is available.
  *			
  * Errors:	Returns appropriate kernel errors on rpc failure.
  *		Returns BOOTSTRAP_UNKNOWN_SERVICE, if service does not exist.
  */
 kern_return_t
 x_bootstrap_status(
-	mach_port_t	bootstrap_port,
-	name_t		service_name,
-	boolean_t	*service_active)
+	mach_port_t		bootstrap_port,
+	name_t			service_name,
+	bootstrap_status_t	*service_active)
 {
 	service_t *servicep;
 	bootstrap_info_t *bootstrap;
@@ -333,18 +551,15 @@ x_bootstrap_status(
 						service_name,
 						service_active);
 		} else {
-#if	DEBUG
 			debug("bootstrap_status service %s unknown",
 				service_name);
-#endif	DEBUG
 			return BOOTSTRAP_UNKNOWN_SERVICE;
 		}
 	}
-	*service_active = servicep->isActive;
-#if	DEBUG
+	*service_active = bsstatus(servicep);
+
 	debug("bootstrap_status server %s %sactive", service_name,
 		servicep->isActive ? "" : "in");
-#endif	DEBUG
 	return BOOTSTRAP_SUCCESS;
 }
 
@@ -355,7 +570,7 @@ x_bootstrap_status(
  *	int *service_names_cnt,
  *	name_array_t *server_names,
  *	int *server_names_cnt,
- *	bool_array_t *service_actives,
+ *	bootstrap_status_array_t *service_actives,
  *	int *service_active_cnt);
  *
  * Returns bootstrap status for all known services.
@@ -364,13 +579,13 @@ x_bootstrap_status(
  */
 kern_return_t
 x_bootstrap_info(
-	mach_port_t	bootstrap_port,
-	name_array_t	*service_namesp,
-	unsigned int	*service_names_cnt,
-	name_array_t	*server_namesp,
-	unsigned int	*server_names_cnt,
-	bool_array_t	*service_activesp,
-	unsigned int	*service_actives_cnt)
+	mach_port_t			bootstrap_port,
+	name_array_t			*service_namesp,
+	unsigned int			*service_names_cnt,
+	name_array_t			*server_namesp,
+	unsigned int			*server_names_cnt,
+	bootstrap_status_array_t	*service_activesp,
+	unsigned int			*service_actives_cnt)
 {
 	kern_return_t result;
 	unsigned int i, cnt;
@@ -379,7 +594,7 @@ x_bootstrap_info(
 	bootstrap_info_t *bootstrap;
 	name_array_t service_names;
 	name_array_t server_names;
-	bool_array_t service_actives;
+	bootstrap_status_array_t service_actives;
 
 	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
 
@@ -424,7 +639,7 @@ x_bootstrap_info(
 	}
 
 	for (  i = 0, servicep = services.next
-	     ; i < nservices
+	     ; i < cnt
 	     ; servicep = servicep->next)
 	{
 	    if (   lookup_service_by_name(bootstrap, servicep->name)
@@ -448,7 +663,7 @@ x_bootstrap_info(
 		    debug("bootstrap info service %s %sactive",
 			servicep->name, servicep->isActive ? "" : "in"); 
 	    }
-	    service_actives[i] = servicep->isActive;
+	    service_actives[i] = bsstatus(servicep);
 	    i++;
 	}
 	*service_namesp = service_names;
@@ -490,23 +705,65 @@ x_bootstrap_subset(
 	bootstrap_info_t *bootstrap;
 	bootstrap_info_t *subset;
 	mach_port_t new_bootstrap_port;
+	mach_port_t previous;
+
+	debug("Subset create attempt: bootstrap %x, requestor: %x",
+	      bootstrap_port, requestor_port);
 
 	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
+	if (!bootstrap || !active_bootstrap(bootstrap))
+		return BOOTSTRAP_NOT_PRIVILEGED;
 
-	result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &new_bootstrap_port);
+	result = mach_port_allocate(
+				mach_task_self(), 
+				MACH_PORT_RIGHT_RECEIVE,
+				&new_bootstrap_port);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "mach_port_allocate");
-	result = mach_port_insert_right(mach_task_self(),  new_bootstrap_port, new_bootstrap_port, MACH_MSG_TYPE_MAKE_SEND);
+
+	result = mach_port_insert_right(
+				mach_task_self(),
+				new_bootstrap_port,
+				new_bootstrap_port,
+				MACH_MSG_TYPE_MAKE_SEND);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "failed to insert send right");
 
-	result = mach_port_move_member(mach_task_self(), new_bootstrap_port, bootstrap_port_set);
+	result = mach_port_insert_member(
+				mach_task_self(),
+				new_bootstrap_port,
+				bootstrap_port_set);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "port_set_add");
 
 	subset = new_bootstrap(bootstrap, new_bootstrap_port, requestor_port);
+
+	result = mach_port_request_notification(
+				mach_task_self(),
+				requestor_port,
+				MACH_NOTIFY_DEAD_NAME,
+				0,
+				notify_port,
+				MACH_MSG_TYPE_MAKE_SEND_ONCE,
+				&previous); 
+	if (result != KERN_SUCCESS) {
+		kern_error(result, "mach_port_request_notification");
+		mach_port_deallocate(mach_task_self(), requestor_port);
+		subset->requestor_port = MACH_PORT_NULL;
+		deactivate_bootstrap(subset);
+	} else if (previous != MACH_PORT_NULL) {
+		debug("deallocating old notification port (%x) for requestor %x",
+			  previous, requestor_port);
+		result = mach_port_deallocate(
+				mach_task_self(),
+				previous);
+		if (result != KERN_SUCCESS)
+			kern_fatal(result, "mach_port_deallocate");
+	}
+
+	info("Created bootstrap subset %x parent %x requestor %x", 
+		new_bootstrap_port, bootstrap_port, requestor_port);
 	*subset_port = new_bootstrap_port;
-	debug("bootstrap_subset new bootstrap %d", new_bootstrap_port);
 	return BOOTSTRAP_SUCCESS;
 }
 
@@ -529,14 +786,17 @@ x_bootstrap_create_service(
 	name_t	service_name,
 	mach_port_t *service_port)
 {
+	server_t *serverp;
 	service_t *servicep;
 	bootstrap_info_t *bootstrap;
 	kern_return_t result;
-	mach_port_t previous;
 
 	bootstrap = lookup_bootstrap_by_port(bootstrap_port);
-	ASSERT(bootstrap);
-	debug("Service creation attempt for service %s", service_name);
+	if (!bootstrap || !active_bootstrap(bootstrap))
+		return BOOTSTRAP_NOT_PRIVILEGED;
+
+	debug("Service creation attempt for service %s bootstrap %x",
+	      service_name, bootstrap_port);
 
 	servicep = lookup_service_by_name(bootstrap, service_name);
 	if (servicep) {
@@ -545,29 +805,27 @@ x_bootstrap_create_service(
 		return BOOTSTRAP_NAME_IN_USE;
 	}
 
+	serverp = lookup_server_by_port(bootstrap_port);
+
 	result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,  service_port);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "port_allocate");
 	result = mach_port_insert_right(mach_task_self(), *service_port, *service_port, MACH_MSG_TYPE_MAKE_SEND);
 	if (result != KERN_SUCCESS)
 		kern_fatal(result, "failed to insert send right");
-#if notyet
-	result = port_set_backup(mach_task_self(), *service_port, backup_port,
-				 &previous);
-	if (result != KERN_SUCCESS)
-		kern_fatal(result, "port_set_backup");
-	info("Declared port %d for service %s", *service_port,
-		service_name);
-#endif /*notyet */
+
+	if (serverp)
+		serverp->activity++;
 
 	servicep = new_service(bootstrap,
 				service_name,
 				*service_port,
 				!ACTIVE,
 				DECLARED,
-				NULL_SERVER);
+				serverp);
 
-	log("Created new service %s", service_name);
+	info("Created new service %x in bootstrap %x: %s", 
+	    servicep->port, bootstrap->bootstrap_port, service_name);
 
 	return BOOTSTRAP_SUCCESS;
 }
diff --git a/mach_init.tproj/testConfig b/mach_init.tproj/testConfig
deleted file mode 100644
index 893009e..0000000
--- a/mach_init.tproj/testConfig
+++ /dev/null
@@ -1,7 +0,0 @@
-services FreeService1 FreeService2;
-# server testServer services BndService3 BndMachService2=2;
-restartable server priority=16 "/NextApps/Terminal" services TerminalService;
-server "/usr/bin/sleep 10" services SleepService;
-self priority=15 Service=2;
-services NetMsgService=0 EnvironService=1 WindowService=3;
-forward;
diff --git a/mach_init.tproj/testConfig2 b/mach_init.tproj/testConfig2
deleted file mode 100644
index fbb72de..0000000
--- a/mach_init.tproj/testConfig2
+++ /dev/null
@@ -1 +0,0 @@
-services foobar;
diff --git a/mach_init.tproj/testServer/Makefile b/mach_init.tproj/testServer/Makefile
deleted file mode 100644
index 25019ea..0000000
--- a/mach_init.tproj/testServer/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-CFLAGS = -g -I..
-
-all: boot_subset testServer listServer
-
-boot_subset: boot_subset.o
-	cc -o boot_subset boot_subset.o
-
-testServer: testServer.o bootstrapUser.o
-	cc -o testServer testServer.o bootstrapUser.o
-
-listServer: listServer.o bootstrapUser.o
-	cc -o listServer listServer.o bootstrapUser.o
-
-
-bootstrapUser.o: ../bootstrapUser.c
-	cc -c -g ../bootstrapUser.c
-
-clean:
-	rm -f *.o testServer listServer
diff --git a/mach_init.tproj/testServer/boot_subset.c b/mach_init.tproj/testServer/boot_subset.c
deleted file mode 100644
index 75c67a7..0000000
--- a/mach_init.tproj/testServer/boot_subset.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Bootstrap subset exercise.
- *
- *	do {
- *		create a subset port with requestor = req_port;
- * 		register "foo" on subset_port;
- *		deallocate req_port; 
- *	} until error;
- */
- 
-#import <sys/types.h>
-#import <mach.h>
-#import <servers/bootstrap.h>
-#import <libc.h>
-#import <mach_error.h>
-
-void log_boot_servers(port_t boot_port);
-
-int main(int argc, char **argv)
-{
-	kern_return_t krtn;
-	port_t subset_port;
-	port_t requestor_port;
-	port_t foo_port;
-	int loop = 0;
-	int deallocate_subset = 0;
-	
-	if (argc >= 2 && argv[1][0] == '-' && argv[1][1] == 'r') {
-		port_t	newboot;
-
-		krtn = bootstrap_look_up(bootstrap_port, &argv[1][2], &newboot);
-		if (krtn) {
-			mach_error("bootstrap lookup", krtn);
-			exit(1);
-		}
-		bootstrap_port = newboot;
-		--argc; ++argv;
-	}
-	if(argc >= 2) {
-		if(argv[1][0] == '-' && argv[1][0] == 'd')
-			deallocate_subset = 1;
-	}
-	
-	/*
-	 * Allocate some resources.
-	 */
-	krtn = port_allocate(task_self(), &foo_port);
-	if(krtn) {
-		mach_error("port_allocate", krtn);
-		exit(1);
-	}
-	
-	do {
-		krtn = port_allocate(task_self(), &requestor_port);
-		if(krtn) {
-			mach_error("port_allocate", krtn);
-			exit(1);
-		}
-		krtn = bootstrap_subset(bootstrap_port,
-			requestor_port,			/* requestor */
-			&subset_port);
-		if(krtn) {
-			mach_error("bootstrap_subset", krtn);
-			break;
-		}
-		printf("Loop %d, prior to bootstrap_register:\n", loop);
-		log_boot_servers(subset_port);	
-		
-		krtn = bootstrap_register(subset_port,
-			"foo",
-			foo_port);
-		if(krtn) {
-			mach_error("bootstrap_register (subset)", krtn);
-			exit(1);
-		}
-		printf("Loop %d, after bootstrap_register:\n", loop);
-		log_boot_servers(subset_port);	
-		
-		/*
-		 * Delete requestor_port, subset should go away.
-		 */
-		krtn = port_deallocate(task_self(), requestor_port);
-		if(krtn) {
-			mach_error("port_deallocate", krtn);
-			exit(1);
-		}
-		
-		if(deallocate_subset) {
-			krtn = port_deallocate(task_self(), subset_port);
-			if(krtn) {
-				mach_error("port_deallocate(subset)", krtn);
-				exit(1);
-			}
-		}
-		loop++;
-	} while(krtn == KERN_SUCCESS);
-
-	printf("...done\n");
-	exit(0);
-}
-
-void log_boot_servers(port_t boot_port)
-{
-	int i;
-	name_array_t service_names;
-	unsigned int service_cnt;
-	name_array_t server_names;
-	unsigned int server_cnt;
-	bool_array_t service_active;
-	unsigned int service_active_cnt;
-	kern_return_t krtn;
-	
-	krtn = bootstrap_info(boot_port, 
-		&service_names, 
-		&service_cnt,
-		&server_names, 
-		&server_cnt, 
-		&service_active, 
-		&service_active_cnt);
-	if (krtn != BOOTSTRAP_SUCCESS)
-		printf("ERROR:  info failed: %d", krtn);
-	else {
-		printf("log_boot_server: service_cnt = %d\n", service_cnt);
-		for (i = 0; i < service_cnt; i++)
-		   	printf("Name: %-15s   Server: %-15s    "
-			    "Active: %-4s",
-			service_names[i],
-			server_names[i][0] == '\0' ? 
-			    "Unknown" : server_names[i],
-			service_active[i] ? "Yes\n" : "No\n");
-	}
-}
-
-   
\ No newline at end of file
diff --git a/mach_init.tproj/testServer/listServer.c b/mach_init.tproj/testServer/listServer.c
deleted file mode 100644
index cc2073d..0000000
--- a/mach_init.tproj/testServer/listServer.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-#import "bootstrap.h"
-
-#import <mach.h>
-#import <stdarg.h>
-#import <stdio.h>
-#import <sys/boolean.h>
-
-#define	NELEM(x)	(sizeof(x)/sizeof(x[0]))
-#define	LAST_ELEMENT(x)	((x)[NELEM(x)-1])
-
-print(const char *format, ...)
-{
-	va_list ap;
-	
-	va_start(ap, format);
-	vfprintf(stderr, format, ap);
-	fprintf(stderr, "\n");
-	va_end(ap);
-}
-
-error(const char *format, ...)
-{
-	va_list ap;
-	
-	va_start(ap, format);
-	fprintf(stderr, "ERROR: ");
-	vfprintf(stderr, format, ap);
-	fprintf(stderr, "\n");
-	va_end(ap);
-}
-
-
-main()
-{
-	kern_return_t result;
-	port_t bootstrap_port;
-	name_array_t service_names;
-	unsigned service_cnt, server_cnt, service_active_cnt;
-	name_array_t server_names;
-	boolean_t *service_actives;
-	int i;
-	
-	result = task_get_bootstrap_port(task_self(), &bootstrap_port);
-	if (result != KERN_SUCCESS) {
-		error("Couldn't get bootstrap port: %d", result);
-		exit(1);
-	}
-	if (bootstrap_port == PORT_NULL) {
-		error("Invalid bootstrap port");
-		exit(1);
-	}
-
-	result = bootstrap_info(bootstrap_port, &service_names, &service_cnt,
-	  &server_names, &server_cnt, &service_actives, &service_active_cnt);
-	if (result != BOOTSTRAP_SUCCESS)
-		error("info failed: %d", result);
-	else {
-		for (i = 0; i < service_cnt; i++)
-			print("Name: %-15s   Server: %-15s    Active: %-4s",
-			 service_names[i],
-			 server_names[i][0] == '\0' ? "Unknown" : server_names[i],
-			 service_actives[i] ? "Yes" : "No");
-	}
-		
-	exit(0);
-}
-	
-	
-
-
diff --git a/mach_init.tproj/testServer/testServer.c b/mach_init.tproj/testServer/testServer.c
deleted file mode 100644
index 8fc640a..0000000
--- a/mach_init.tproj/testServer/testServer.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-#import "bootstrap.h"
-
-#import <mach.h>
-#import <stdarg.h>
-#import <stdio.h>
-#import <sys/boolean.h>
-
-#define	NELEM(x)	(sizeof(x)/sizeof(x[0]))
-#define	LAST_ELEMENT(x)	((x)[NELEM(x)-1])
-
-print(const char *format, ...)
-{
-	va_list ap;
-	
-	va_start(ap, format);
-	vfprintf(stderr, format, ap);
-	fprintf(stderr, "\n");
-	va_end(ap);
-}
-
-error(const char *format, ...)
-{
-	va_list ap;
-	
-	va_start(ap, format);
-	fprintf(stderr, "ERROR: ");
-	vfprintf(stderr, format, ap);
-	fprintf(stderr, "\n");
-	va_end(ap);
-}
-
-
-main()
-{
-	kern_return_t result;
-	port_t bootstrap_port, port, myport;
-	port_type_t ptype;
-	port_t *mach_ports;
-	port_t *ports;
-	unsigned port_cnt;
-	unsigned mach_ports_cnt;
-	name_t name_array[4];
-	boolean_t all_known;
-	port_t unpriv_port;
-	port_t subset_port;
-	port_t sub_reg_port;
-	boolean_t active;
-	name_array_t service_names;
-	unsigned service_cnt, server_cnt, service_active_cnt;
-	name_array_t server_names;
-	boolean_t *service_actives;
-	int i;
-	
-	print("test server running");
-	result = task_get_bootstrap_port(task_self(), &bootstrap_port);
-	if (result != KERN_SUCCESS) {
-		error("Couldn't get bootstrap port: %d", result);
-		exit(1);
-	} else
-		print("Bootstrap port is %d", bootstrap_port);
-	if (bootstrap_port == PORT_NULL) {
-		error("Invalid bootstrap port");
-		exit(1);
-	}
-	
-	/*
-	 * Try a checkin
-	 */
-	print("Checkin test 1");
-	result = bootstrap_check_in(bootstrap_port, "FreeService1", &port);
-	if (result != BOOTSTRAP_SUCCESS)
-		error("Checkin failed: %d", result);
-	else {
-		result = port_type(task_self(), port, &ptype);
-		if (result != KERN_SUCCESS)
-			error("port type failed: %d", result);
-		else
-			print("Checkin returned port type 0x%x", ptype);
-		/*
-		 * Try a status request
-		 */
-		result = bootstrap_status(bootstrap_port, "FreeService1", &active);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("Status failed: %d", result);
-		else if (active != TRUE)
-			error("Service shown inactive");
-	}
-	
-	/*
-	 * Try a lookup
-	 */
-	print("lookup test");
-	result = bootstrap_look_up(bootstrap_port, "FreeService2", &port);
-	if (result != BOOTSTRAP_SUCCESS)
-		error("lookup failed: %d", result);
-	else {
-		result = port_type(task_self(), port, &ptype);
-		if (result != KERN_SUCCESS)
-			error("port type failed: %d", result);
-		else
-			print("Lookup returned port type 0x%x", ptype);
-		/*
-		 * Try a status request
-		 */
-		result = bootstrap_status(bootstrap_port, "FreeService2", &active);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("Status failed: %d", result);
-		else if (active != FALSE)
-			error("Service shown active");
-	}
-	
-	/*
-	 * Test that mach ports are initialized
-	 */
-	print("mach ports test");
-	result = mach_ports_lookup(task_self(), &mach_ports, &mach_ports_cnt);
-	if (result != KERN_SUCCESS)
-		error("mach_ports_lookup failed: %d", result);
-	else {
-		result = bootstrap_look_up(bootstrap_port, "NetMsgService", &port);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("Lookup of NetMsgService failed: %d", result);
-		else if (port != mach_ports[0])
-			error("mach ports not setup correctly for NetMsgService");
-		
-		result = bootstrap_look_up(bootstrap_port, "EnvironService", &port);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("Lookup of EnvironService failed: %d", result);
-		else if (port != mach_ports[1])
-			error("mach ports not setup correctly for EnvironService");
-
-		result = bootstrap_look_up(bootstrap_port, "Service", &port);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("Lookup of Service failed: %d", result);
-		else if (port != mach_ports[2])
-			error("mach ports not setup correctly for Service");
-			
-		result = bootstrap_look_up(bootstrap_port, "WindowService", &port);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("Lookup of WindowService failed: %d", result);
-		else if (port != mach_ports[3])
-			error("mach ports not setup correctly for WindowService");
-	}
-	
-	/*
-	 * Try doing a checkin with the old service interface
-	 */
-	result = service_checkin(mach_ports[2], mach_ports[1], &myport);
-	if (result != KERN_SUCCESS)
-		error("service checkin failed: %d", result);
-	else {
-		result = port_type(task_self(), myport, &ptype);
-		if (result != KERN_SUCCESS)
-			error("port type failed: %d", result);
-		else
-			print("Checkin returned port type 0x%x", ptype);
-	}
-	
-	/*
-	 * Try a register
-	 */
-	print("register test");
-	print("...Dynamic creation");
-	result = port_allocate(task_self(), &myport);
-	if (result != KERN_SUCCESS)
-		error("couldn't allocate port: %d", result);
-	else {
-		result = bootstrap_register(bootstrap_port, "NewService", myport);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("Couldn't register port: %d", result);
-		else {
-	
-			/*
-			 * Try a lookup on just registered port
-			 */
-			result = bootstrap_look_up(bootstrap_port, "NewService", &port);
-			if (result != BOOTSTRAP_SUCCESS)
-				error("lookup failed: %d", result);
-			else {
-				result = port_type(task_self(), port, &ptype);
-				if (result != KERN_SUCCESS)
-					error("port type failed: %d", result);
-				else {
-					print("Lookup returned port type 0x%x", ptype);
-					if (port != myport)
-						error("lookup didn't match register");
-				}
-			}
-			
-			/*
-			 * Try re-registering service name
-			 */
-			result = bootstrap_register(bootstrap_port, "NewService", myport);
-			if (result != BOOTSTRAP_SERVICE_ACTIVE)
-				error("Unexpected register response: %d", result);
-
-			/*
-			 * Delete the port.  This should cause the service to go away
-			 * in the server.
-			 */
-			port_deallocate(task_self(), myport);
-			
-			result = bootstrap_look_up(bootstrap_port, "NewService", &port);
-			if (result != BOOTSTRAP_UNKNOWN_SERVICE)
-				error("service active after port deleted");
-		}
-	}
-
-	print("...Declared service");
-	result = port_allocate(task_self(), &myport);
-	if (result != KERN_SUCCESS)
-		error("couldn't allocate port: %d", result);
-	else {
-		result = bootstrap_register(bootstrap_port, "FreeService2", myport);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("Couldn't register port: %d", result);
-		else {
-	
-			/*
-			 * Try a lookup on just registered port
-			 */
-			result = bootstrap_look_up(bootstrap_port, "FreeService2", &port);
-			if (result != BOOTSTRAP_SUCCESS)
-				error("lookup failed: %d", result);
-			else {
-				result = port_type(task_self(), port, &ptype);
-				if (result != KERN_SUCCESS)
-					error("port type failed: %d", result);
-				else {
-					print("Lookup returned port type 0x%x", ptype);
-					if (port != myport)
-						error("lookup didn't match register");
-				}
-			}
-			
-			/*
-			 * Delete the port.  This should cause service to revert.
-			 */
-			port_deallocate(task_self(), myport);
-			
-			result = bootstrap_status(bootstrap_port, "FreeService2", &active);
-			if (result != BOOTSTRAP_SUCCESS)
-				error("Status failed: %d", result);
-			else if (active != FALSE)
-				error("Service shown active");
-		}
-	}
-
-	/*
-	 * Try a checkin on a port bound to Terminal server
-	 */
-	print("Bound checkin test -- Terminal");
-	result = bootstrap_check_in(bootstrap_port, "TerminalService", &port);
-	if (result != BOOTSTRAP_SUCCESS)
-		error("Checkin of TerminalService failed: %d", result);
-	else {
-		result = port_type(task_self(), port, &ptype);
-		if (result != KERN_SUCCESS)
-			error("port type failed: %d", result);
-		print("Checkin returned port type 0x%x", ptype);
-	}
-
-	/*
-	 * Try a checkin on a port bound to Sleep server
-	 */
-	print("Bound checkin test -- Sleep");
-	result = bootstrap_check_in(bootstrap_port, "SleepService", &port);
-	if (result != BOOTSTRAP_SUCCESS)
-		print("Checkin of SleepService failed (as expected): %d",
-			result);
-	else {
-		result = port_type(task_self(), port, &ptype);
-		if (result != KERN_SUCCESS)
-			error("port type failed: %d", result);
-		error("Checkin returned port type 0x%x(didn't fail!)", ptype);
-	}
-
-	/*
-	 * Try a lookup_array
-	 */
-	print("Lookup array test");
-	
-	strncpy(&name_array[0], "NetMsgService", sizeof(name_array[0]));
-	LAST_ELEMENT(name_array[0]) = '\0';
-	strncpy(&name_array[1], "EnvironService", sizeof(name_array[1]));
-	LAST_ELEMENT(name_array[1]) = '\0';
-	strncpy(&name_array[2], "Service", sizeof(name_array[2]));
-	LAST_ELEMENT(name_array[2]) = '\0';
-	strncpy(&name_array[3], "WindowService", sizeof(name_array[3]));
-	LAST_ELEMENT(name_array[3]) = '\0';
-	
-	result = bootstrap_look_up_array(bootstrap_port, name_array, 4, &ports,
-	 &port_cnt, &all_known);
-	if (result != BOOTSTRAP_SUCCESS)
-		error("Lookup array failed: %d", result);
-	else {
-		print("Port count = %d, all known = %d", port_cnt, all_known);
-		for (i = 0; i < 4; i++)
-			if (ports[i] != mach_ports[i])
-				error("port mismatch on port %d", i);
-	}
-	
-	/*
-	 * Get an unprivileged port
-	 */
-	print("Unprivileged port test");
-	result = port_allocate(task_self(), &myport);
-	result = bootstrap_get_unpriv_port(bootstrap_port, &unpriv_port);
-	if (result != BOOTSTRAP_SUCCESS)
-		error("Couldn't get unpriv port: %d", result);
-	else {
-		/*
-		 * Try doing an unpriv operation
-		 */
-		result = bootstrap_look_up(unpriv_port, "FreeService2", &port);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("lookup failed: %d", result);
-		/*
-		 * Try doing a privileged operation
-		 */
-		result = bootstrap_register(unpriv_port, "ANewService", myport);
-		if (result != BOOTSTRAP_NOT_PRIVILEGED)
-			error("Unexpected register port response: %d", result);
-
-		/*
-		 * Try creating a subset port.
-		 */
-		result = bootstrap_subset(unpriv_port, task_self(),
-			&subset_port);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("Couldn't get subset port from unpriv %d",
-				result);
-	}
-
-	/*
-	 * Get a subset port.
-	 */
-	print("Subset port test");
-	result = bootstrap_subset(bootstrap_port, task_self(), &subset_port);
-	if (result != BOOTSTRAP_SUCCESS)
-		error("Couldn't get subset port: %d", result);
-	else {
-
-		/*
-		 * Register a port.
-		 */
-		result = port_allocate(task_self(), &sub_reg_port);
-		if (result != KERN_SUCCESS)
-			error("port_allocate of sub_reg_port failed %d",
-				result);
-		result = bootstrap_register(subset_port, "SubsetReg",
-					    sub_reg_port);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("register of SubsetReg failed on subset port %d",
-				result);
-		/*
-		 * Check that port registered only in subset.
-		 */
-		result = bootstrap_status(bootstrap_port, "SubsetReg",
-					&active);
-		if (result != BOOTSTRAP_UNKNOWN_SERVICE)
-			error("status of SubsetReg  ok on bootstrap! %d",
-				result);
-		result = bootstrap_status(subset_port, "SubsetReg",
-					&active);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("status of SubsetReg failed on subset port %d",
-				result);
-		if (!active)
-			error("SubsetReg isn't active");
-
-
-		/*
-		 * Try an info request.
-		 */
-		print("Subset info request");
-		result = bootstrap_info(subset_port, &service_names,
-			&service_cnt,
-			&server_names, &server_cnt, &service_actives,
-			&service_active_cnt);
-		if (result != BOOTSTRAP_SUCCESS)
-			error("info failed: %d", result);
-		else {
-			for (i = 0; i < service_cnt; i++)
-				print("Name: %s	Server: %s	Active: %s",
-				    service_names[i],
-				    server_names[i][0] == '\0'
-				     ? "Unknown"
-				     : server_names[i],
-				    service_actives[i] ? "Yes" : "No");
-		}
-	}
-
-	/*
-	 * Try an info request
-	 */
-	print("Info test");
-	result = bootstrap_info(bootstrap_port, &service_names, &service_cnt,
-	  &server_names, &server_cnt, &service_actives, &service_active_cnt);
-	if (result != BOOTSTRAP_SUCCESS)
-		error("info failed: %d", result);
-	else {
-		for (i = 0; i < service_cnt; i++)
-			print("Name: %s	Server: %s	Active: %s", service_names[i],
-			 server_names[i][0] == '\0' ? "Unknown" : server_names[i],
-			 service_actives[i] ? "Yes" : "No");
-	}
-		
-	exit(0);
-}
-
-
-
diff --git a/mkfile.tproj/Makefile b/mkfile.tproj/Makefile
index 9a46e78..998b2d2 100644
--- a/mkfile.tproj/Makefile
+++ b/mkfile.tproj/Makefile
@@ -14,7 +14,7 @@ PROJECT_TYPE = Tool
 
 CFILES = mkfile.c
 
-OTHERSRCS = Makefile.preamble
+OTHERSRCS = Makefile.preamble Makefile.postamble mkfile.8
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
diff --git a/mkfile.tproj/Makefile.postamble b/mkfile.tproj/Makefile.postamble
new file mode 100644
index 0000000..01925dd
--- /dev/null
+++ b/mkfile.tproj/Makefile.postamble
@@ -0,0 +1,3 @@
+after_install:
+	install -d $(DSTROOT)/usr/share/man/man8
+	install -c -m 444 mkfile.8 $(DSTROOT)/usr/share/man/man8
diff --git a/mkfile.tproj/mkfile.8 b/mkfile.tproj/mkfile.8
new file mode 100644
index 0000000..beed0c1
--- /dev/null
+++ b/mkfile.tproj/mkfile.8
@@ -0,0 +1,47 @@
+.\" (c) 1997 Apple Computer, Inc.
+.TH MKFILE 8 "1 September 1997"
+.SH NAME
+mkfile \- create a file
+.SH SYNOPSIS
+.B mkfile
+.RB [ " -nv " ]
+.I size\c
+[\c
+.BR b | k | m | g\c
+]
+.IR filename " .\|.\|."
+.SH DESCRIPTION
+.B mkfile
+creates one or more files that are suitable for use as
+.SM NFS-\s0mounted
+swap areas.  The sticky bit is set, and
+the file is padded with zeroes by default.
+Non-root users must set the sticky bit using
+chmod(1).
+The default size unit is bytes, but the following suffixes
+may be used to multiply by the given factor:
+.B b
+(512),
+.B k
+(1024),
+.B m
+(1048576), and
+.B g
+(1073741824).
+.SH OPTIONS
+.TP
+.B \-n
+Create an empty
+.IR filename .
+The size is noted, but disk blocks aren't allocated until data is
+written to them.
+.TP
+.B \-v
+Verbose.  Report the names and sizes of created files.
+.SH WARNING
+If a client's swap file is removed and recreated, it must be
+re-exported before the client will be able to access it.
+This action may only be done when the client is not running.
+.SH "SEE ALSO"
+.TP
+chmod(2), stat(2), exportfs(8), sticky(8)
diff --git a/nologin.tproj/Makefile.postamble b/nologin.tproj/Makefile.postamble
index 6979d87..2cd9b35 100644
--- a/nologin.tproj/Makefile.postamble
+++ b/nologin.tproj/Makefile.postamble
@@ -121,9 +121,16 @@
 # Note: on MS Windows, executables, have an extension, so rules and dependencies
 #       for generated tools should use $(EXECUTABLE_EXT) on the end.
 
+SHAREDIR = /usr/share
+MANDIR   = $(SHAREDIR)/man/man8
+MANPAGE  = nologin.8
+
 nologin: nologin.sh
 	$(CP) nologin.sh ${SYM_DIR}/nologin
 
 after_install::
 	$(CP) -p ${SYM_DIR}/nologin $(DSTROOT)$(INSTALLDIR)/nologin
 	$(CHMOD) 555 $(DSTROOT)$(INSTALLDIR)/nologin
+	$(MKDIRS) $(DSTROOT)$(MANDIR)
+	$(CP) -f $(MANPAGE) $(DSTROOT)$(MANDIR)/$(MANPAGE)
+	$(CHMOD) og-w $(DSTROOT)$(MANDIR)/$(MANPAGE)
diff --git a/nologin.tproj/nologin.8 b/nologin.tproj/nologin.8
index 32a7e73..07ddc98 100644
--- a/nologin.tproj/nologin.8
+++ b/nologin.tproj/nologin.8
@@ -1,3 +1,6 @@
+.\"	$OpenBSD: nologin.8,v 1.3 1997/02/16 04:15:32 downsj Exp $
+.\"	$NetBSD: nologin.8,v 1.3 1995/03/18 14:59:09 cgd Exp $
+.\"
 .\" Copyright (c) 1993
 .\"	The Regents of the University of California.  All rights reserved.
 .\"
@@ -31,9 +34,9 @@
 .\"
 .\"     @(#)nologin.8	8.1 (Berkeley) 6/19/93
 .\"
-.Dd June 19, 1993
+.Dd February 15, 1997
 .Dt NOLOGIN 8
-.Os BSD 4.4
+.Os
 .Sh NAME
 .Nm nologin
 .Nd politely refuse a login 
@@ -45,6 +48,12 @@ displays a message that an account is not available and
 exits non-zero.
 It is intended as a replacement shell field for accounts that
 have been disabled.
+.Pp
+If the file
+.Pa /etc/nologin.txt
+exists,
+.Nm nologin
+displays its contents to the user instead of the default message.
 .Sh SEE ALSO
 .Xr login 1
 .Sh HISTORY
diff --git a/nvram.tproj/nvram.8 b/nvram.tproj/nvram.8
index 7392f2e..57d22d5 100644
--- a/nvram.tproj/nvram.8
+++ b/nvram.tproj/nvram.8
@@ -27,8 +27,8 @@ In principle,
 .IR name
 can be any string.  In practice, not all strings will be accepted.
 Old world machines have a fixed set of Open Firmware variables.
-New World machines can create new varibles as desired.  Some variables
-require adminstrator privilege to get or set.
+New World machines can create new variables as desired.  Some variables
+require administrator privilege to get or set.
 .LP
 The given
 .IR value
@@ -72,14 +72,14 @@ list name=value statements.  If the last character of a line is
 example% nvram boot-args="-s rd=*hd:10"
 .RE
 .LP
-Set the boot-args variable to "-s rd=*hd:10".  This would specifiy
+Set the boot-args variable to "-s rd=*hd:10".  This would specify
 single user mode with the root device in hard drive partition 10.
 .LP
 .RS
 example% nvram my-variable="String One%00String Two%00%00"
 .RE
 .LP
-Create a new variable, my-variable, containging a list of two
+Create a new variable, my-variable, containing a list of two
 C-strings that is terminated by a NUL.
 .SH FILES
 .PD 0
diff --git a/nvram.tproj/nvram.c b/nvram.tproj/nvram.c
index d23b79c..c450f32 100644
--- a/nvram.tproj/nvram.c
+++ b/nvram.tproj/nvram.c
@@ -409,10 +409,11 @@ static void PrintOFVariable(const void *key, const void *value, void *context)
   long          cnt, cnt2;
   const char    *nameString;
   char          numberBuffer[10];
-  char          *dataPtr, dataChar;
+  const uint8_t *dataPtr;
+  uint8_t       dataChar;
   char          *dataBuffer = 0;
-  char          *valueString = 0;
-  unsigned long number, length;
+  const char    *valueString = 0;
+  uint32_t      number, length;
   CFTypeID      typeID;
   
   // Get the OF variable's name.
diff --git a/sc_usage.tproj/Makefile b/sc_usage.tproj/Makefile
index 6f57646..f50e9a5 100644
--- a/sc_usage.tproj/Makefile
+++ b/sc_usage.tproj/Makefile
@@ -24,7 +24,7 @@ MAKEFILE = tool.make
 NEXTSTEP_INSTALLDIR = /usr/bin
 WINDOWS_INSTALLDIR = /Library/Executables
 PDO_UNIX_INSTALLDIR = /bin
-LIBS = 
+LIBS = -lcurses
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
diff --git a/sc_usage.tproj/sc_usage.c b/sc_usage.tproj/sc_usage.c
index 5198d9a..965d369 100644
--- a/sc_usage.tproj/sc_usage.c
+++ b/sc_usage.tproj/sc_usage.c
@@ -23,7 +23,7 @@
  */
 
 /*
-cc -I. -DKERNEL_PRIVATE -O -o sc_usage sc_usage.c
+cc -I. -DKERNEL_PRIVATE -O -o sc_usage sc_usage.c -lncurses
 */
 
 #define	Default_DELAY	1	/* default delay interval */
@@ -42,7 +42,7 @@ cc -I. -DKERNEL_PRIVATE -O -o sc_usage sc_usage.c
 
 #include <libc.h>
 #include <termios.h>
-#include <bsd/curses.h>
+#include <curses.h>
 
 #include <sys/ioctl.h>
 
@@ -192,7 +192,6 @@ int    scalls;
 #define DIVISOR 16.6666        /* Trace divisor converts to microseconds */
 double divisor = DIVISOR;
 
-struct termios tmode, omode;
 
 int mib[6];
 size_t needed;
@@ -226,8 +225,6 @@ void leave()			/* exit under normal conditions -- INT handler */
 	        move(LINES - 1, 0);
 		refresh();
 		endwin();
-
-		tcsetattr(0, TCSANOW, &omode);
 	}
 	set_enable(0);
 	set_pidcheck(pid, 0);
@@ -243,8 +240,6 @@ char *s;
 	        move(LINES - 1, 0);
 		refresh();
 		endwin();
-
-		tcsetattr(0, TCSANOW, &omode);
 	}
 
         printf("sc_usage: ");
@@ -423,22 +418,17 @@ main(argc, argv)
 
 
 	if (no_screen_refresh == 0) {
-	        if (tcgetattr(0, &tmode) < 0) {
-		        printf("can't get terminal attributes\n");
-			exit(1);
-		}
-		omode = tmode;
-	
-		tmode.c_lflag &= ~ICANON;
-		tmode.c_cc[VMIN] = 0;
-		tmode.c_cc[VTIME] = 1;
 
-		if (tcsetattr(0, TCSANOW, &tmode) < 0) {
-		        printf("can't set terminal attributes\n");
-			exit(1);
-		}
 	        /* initializes curses and screen (last) */
-	        initscr();
+		if (initscr() == (WINDOW *) 0)
+		  {
+		    printf("Unrecognized TERM type, try vt100\n");
+		    exit(1);
+		  }
+		cbreak();
+		timeout(100);
+		noecho();
+
 		clear();
 		refresh();
 	}
@@ -447,6 +437,8 @@ main(argc, argv)
 	/* set up signal handlers */
 	signal(SIGINT, leave);
 	signal(SIGQUIT, leave);
+        signal(SIGHUP, leave);
+        signal(SIGTERM, leave);
 	signal(SIGWINCH, sigwinch);
 
         if (no_screen_refresh == 0)
@@ -480,21 +472,16 @@ main(argc, argv)
 	while (1) {
 	        int     i;
 		int     cnt;
-		char    ibuf[128];
+		char    c;
 		void    sample_sc();
 		
 	        for (i = 0; i < (10 * delay) && newLINES == 0; i++) {
 
 			if (no_screen_refresh == 0) {
-			        if ((cnt = read(0, &ibuf, 128)) > 0) {
-				        int   n;
-
-					for (n = 0; n < cnt; n++)
-					        if (ibuf[n] == 'q')
-						        leave();
-					reset_counters();
-					break;
-				}
+			        if ((c = getch()) != ERR && (char)c == 'q') 
+				        leave();
+				if (c != ERR)
+				        reset_counters();
 			} else
 			        usleep(100000);
 			sample_sc();
@@ -502,7 +489,11 @@ main(argc, argv)
 		(void)sort_scalls();
 
 	        if (newLINES) {
-		        initscr();
+		        /*
+			  No need to check for initscr error return.
+			  We won't get here if it fails on the first call.
+			*/
+		        endwin();
 			clear();
 			refresh();
 
@@ -1425,11 +1416,12 @@ sample_sc()
 		        (uint64_t)((unsigned int)(kd[i].timestamp.tv_nsec));
 		baseid = debugid & 0xffff0000;
 
-		if (debugid == vfs_lookup) {
+		if (type == vfs_lookup) {
 		        long *sargptr;
 
 		        if ((ti = find_thread(thread)) == (struct th_info *)0)
 			        continue;
+
 		        if (ti->vfslookup == 1) {
 			        ti->vfslookup++;
 				memset(&ti->pathname[0], 0, (PATHLENGTH + 1));
@@ -1451,7 +1443,21 @@ sample_sc()
 				*/
 
 				if ((long *)sargptr >= (long *)&ti->pathname[PATHLENGTH])
-				  continue;
+					continue;
+
+				/*
+				  We need to detect consecutive vfslookup entries.
+				  So, if we get here and find a START entry,
+				  fake the pathptr so we can bypass all further
+				  vfslookup entries.
+				*/
+
+				if (debugid & DBG_FUNC_START)
+				  {
+				    (long *)ti->pathptr = (long *)&ti->pathname[PATHLENGTH];
+				    continue;
+				  }
+
 				*sargptr++ = kd[i].arg1;
 				*sargptr++ = kd[i].arg2;
 				*sargptr++ = kd[i].arg3;
diff --git a/sc_usage.tproj/trace.codes b/sc_usage.tproj/trace.codes
index 25331b5..a2caffd 100644
--- a/sc_usage.tproj/trace.codes
+++ b/sc_usage.tproj/trace.codes
@@ -1,4 +1,65 @@
-773
+892
+0x1f000000	DYLD_initialize
+0x1f010000	DYLD_CALL_image_init_routine
+0x1f010004	DYLD_CALL_dependent_init_routine
+0x1f010008	DYLD_CALL_lazy_init_routine
+0x1f01000c	DYLD_CALL_module_init_for_library
+0x1f010010	DYLD_CALL_module_init_for_object
+0x1f010014	DYLD_CALL_module_terminator_for_object
+0x1f010018	DYLD_CALL_module_init_for_dylib
+0x1f01001c	DYLD_CALL_mod_term_func
+0x1f010020	DYLD_CALL_object_func
+0x1f010024	DYLD_CALL_library_func
+0x1f010028	DYLD_CALL_add_image_func
+0x1f01002c	DYLD_CALL_remove_image_func
+0x1f010030	DYLD_CALL_link_object_module_func
+0x1f010034	DYLD_CALL_link_library_module_func
+0x1f010038	DYLD_CALL_link_module_func
+0x1f020000	DYLD_lookup_and_bind_with_hint
+0x1f020004	DYLD_lookup_and_bind_fully
+0x1f020008	DYLD_link_module
+0x1f02000c	DYLD_ulink_module
+0x1f020010	DYLD_bind_objc_module
+0x1f020014	DYLD_bind_fully_image_containing_address
+0x1f020018	DYLD_make_delayed_module_initializer_calls
+0x1f02001c	DYLD_NSNameOfSymbol
+0x1f020020	DYLD_NSAddressOfSymbol
+0x1f020024	DYLD_NSModuleForSymbol
+0x1f020028	DYLD_NSLookupAndBindSymbolWithHint
+0x1f02002c	DYLD_NSLookupSymbolInModule
+0x1f020030	DYLD_NSLookupSymbolInImage
+0x1f020034	DYLD_NSIsSymbolNameDefined
+0x1f020038	DYLD_NSIsSymbolNameDefinedWithHint
+0x1f02003c	DYLD_NSIsSymbolNameDefinedInImage
+0x1f020040	DYLD_NSNameOfModule
+0x1f020044	DYLD_NSLibraryNameForModule
+0x1f020048	DYLD_NSAddLibrary
+0x1f02004c	DYLD_NSAddLibraryWithSearching
+0x1f020050	DYLD_NSAddImage
+0x1f030000	DYLD_lookup_symbol
+0x1f030004	DYLD_bind_lazy_symbol_reference
+0x1f030008	DYLD_bind_symbol_by_name
+0x1f03000c	DYLD_link_in_need_modules
+0x1f040000	DYLD_map_image
+0x1f040004	DYLD_load_executable_image
+0x1f040008	DYLD_load_library_image
+0x1f04000c	DYLD_map_library_image
+0x1f040010	DYLD_map_bundle_image
+0x1f040014	DYLD_load_dependent_libraries
+0x1f040018	DYLD_notify_prebinding_agent
+0x1fff0000	LAUNCH_START_FINDER
+0x1fff0100	LAUNCH_START_DOCK
+0x1fff0200	LAUNCH_LSOpen
+0x1fff0204	LAUNCH_LSRegisterItem
+0x1fff0208	LAUNCH_LSGetApplicationAndFlagsForInfo
+0x1fff0300	LAUNCH_CPSLaunch
+0x1fff0304	LAUNCH_CPSRegisterwithServer
+0x1fff0308	LAUNCH_CGSCheckInNewProcess
+0x1fff030c      LAUNCH_CPSExecProcess
+0x1fff0310	LAUNCH_APP_EnterEventLoop
+0x1fff0314	LAUNCH_APP_WillOpenUntitled
+0x1fff031c	LAUNCH_APP_DidOpenUntitled
+0x1fffffff	LAUNCH_END
 0xff000104  	MSG_mach_notify_port_deleted
 0xff000114  	MSG_mach_notify_port_destroyed
 0xff000118  	MSG_mach_notify_no_senders
@@ -30,7 +91,7 @@
 0xff000658  	MSG_vm_allocate_cpm
 0xff00065c  	MSG_host_processors
 0xff000660  	MSG_host_get_clock_control
-0xff000664  	MSG_kmod_create
+0xff000664  	MSG_kmod_creat
 0xff000668  	MSG_kmod_destroy
 0xff00066c  	MSG_kmod_control
 0xff000670  	MSG_host_get_special_port
@@ -89,6 +150,8 @@
 0xff002584  	MSG_exception_raise
 0xff002588  	MSG_exception_raise_state
 0xff00258c  	MSG_exception_raise_state_identity
+0xff002648  	MSG_samples
+0xff00264c  	MSG_notices
 0xff002bc0  	MSG_io_object_get_class
 0xff002bc4  	MSG_io_object_conforms_to
 0xff002bc8  	MSG_io_iterator_next
@@ -160,7 +223,6 @@
 0xff003218  	MSG_mach_port_deallocate
 0xff00321c  	MSG_mach_port_get_refs
 0xff003220  	MSG_mach_port_mod_refs
-0xff003224  	MSG_mach_port_allocate_subsystem
 0xff003228  	MSG_mach_port_set_mscount
 0xff00322c  	MSG_mach_port_get_set_status
 0xff003230  	MSG_mach_port_move_member
@@ -212,7 +274,6 @@
 0xff003598  	MSG_task_assign_default
 0xff00359c  	MSG_task_get_assignment
 0xff0035a0  	MSG_task_set_policy
-0xff0035a4  	MSG_mach_subsystem_create
 0xff003840  	MSG_thread_terminate
 0xff003844  	MSG_act_get_state
 0xff003848  	MSG_act_set_state
@@ -298,11 +359,20 @@
 0xff25a8ac  	MSG_lock_make_stable
 0xff25a8b0  	MSG_lock_handoff
 0xff25a8b4  	MSG_lock_handoff_accept
+0xff25abc0  	MSG_semaphore_signal
+0xff25abc4  	MSG_semaphore_signal_all
+0xff25abc8  	MSG_semaphore_wait
+0xff25abcc  	MSG_semaphore_signal_thread
+0xff25abd0  	MSG_semaphore_timedwait
+0xff25abd4  	MSG_semaphore_wait_signal
+0xff25abd8  	MSG_semaphore_timedwait_signal
 0xff3d0904  	MSG_bootstrap_ports
 0xff3d0908  	MSG_bootstrap_arguments
 0xff3d090c  	MSG_bootstrap_environment
 0xff3d0910  	MSG_bootstrap_completed
+0xffbebdcc  	MSG_clock_alarm_reply
 0x1300000 	MACH_vmfault
+0x1300004 	MACH_Pageout
 0x1400000 	MACH_SCHED
 0x1400008 	MACH_STKHANDOFF
 0x1400018 	MACH_MKRUNNABLE
@@ -340,7 +410,7 @@
 0x10c0070 	MSC_task_self_trap
 0x10c0074 	MSC_host_self_trap
 0x10c0078 	MSC_kern_invalid_#30
-0x10c007c 	MSC_kern_invalid_#31
+0x10c007c 	MSC_mach_msg_trap
 0x10c0080 	MSC_mach_msg_overwrite_trap
 0x10c0084 	MSC_semaphore_signal_trap
 0x10c0088 	MSC_semaphore_signal_all_trap
@@ -439,6 +509,30 @@
 0x10c01fc 	MSC_kern_invalid_#127
 0x1050000 	INTERRUPT
 0x3010090 	VFS_LOOKUP
+0x3020000       P_WrData
+0x3020008       P_RdData
+0x3020020       P_WrMeta
+0x3020028       P_RdMeta
+0x3020040       P_PgOut
+0x3020048       P_PgIn
+0x3020010       P_WrDataAsync
+0x3020018       P_RdDataAsync
+0x3020030       P_WrMetaAsync
+0x3020038       P_RdMetaAsync
+0x3020050       P_PgOutAsync
+0x3020058       P_PgInAsync
+0x3020004       P_WrDataDone
+0x302000C       P_RdDataDone
+0x3020024       P_WrMetaDone
+0x302002C       P_RdMetaDone
+0x3020044       P_PgOutDone
+0x302004C       P_PgInDone
+0x3020014       P_WrDataAsyncDone
+0x302001C       P_RdDataAsyncDone
+0x3020034       P_WrMetaAsyncDone
+0x302003C       P_RdMetaAsyncDone
+0x3020054       P_PgOutAsyncDone
+0x302005C       P_PgInAsyncDone
 0x40c0000 	BSC_SysCall
 0x40c0004 	BSC_exit
 0x40c0008 	BSC_fork
@@ -447,7 +541,7 @@
 0x40c0014 	BSC_open
 0x40c0018 	BSC_close
 0x40c001c 	BSC_wait4
-0x40c0020 	BSC_old_creat
+0x40c0020 	BSC_obs_creat
 0x40c0024 	BSC_link
 0x40c0028 	BSC_unlink
 0x40c002c 	BSC_obs_execv
@@ -456,8 +550,8 @@
 0x40c0038 	BSC_mknod
 0x40c003c 	BSC_chmod
 0x40c0040 	BSC_chown
-0x40c0044 	BSC_sbreak
-0x40c0048 	BSC_getfsstat
+0x40c0044 	BSC_obs_break
+0x40c0048 	BSC_obs_getfsstat
 0x40c004c 	BSC_old_lseek
 0x40c0050 	BSC_getpid
 0x40c0054 	BSC_obs_mount
@@ -477,9 +571,9 @@
 0x40c008c 	BSC_fchflags
 0x40c0090 	BSC_sync
 0x40c0094 	BSC_kill
-0x40c0098 	BSC_old_stat
+0x40c0098 	BSC_obs_stat
 0x40c009c 	BSC_getppid
-0x40c00a0 	BSC_old_lstat
+0x40c00a0 	BSC_obs_lstat
 0x40c00a4 	BSC_dup
 0x40c00a8 	BSC_pipe
 0x40c00ac 	BSC_getegid
@@ -501,22 +595,22 @@
 0x40c00ec 	BSC_execve
 0x40c00f0 	BSC_umask
 0x40c00f4 	BSC_chroot
-0x40c00f8 	BSC_old_fstat
-0x40c00fc 	BSC_old_getkerninfo
-0x40c0100 	BSC_old_getpagesize
+0x40c00f8 	BSC_obs_fstat
+0x40c00fc 	BSC_#63
+0x40c0100 	BSC_obs_getpagesize
 0x40c0104 	BSC_msync
 0x40c0108 	BSC_vfork
 0x40c010c 	BSC_obs_vread
 0x40c0110 	BSC_obs_vwrite
 0x40c0114 	BSC_sbrk
 0x40c0118 	BSC_sstk
-0x40c011c 	BSC_old_mmap
+0x40c011c 	BSC_obs_mmap
 0x40c0120 	BSC_obs_vadvise
 0x40c0124 	BSC_munmap
 0x40c0128 	BSC_mprotect
 0x40c012c 	BSC_madvise
-0x40c0130 	BSC_obs_vhangup
-0x40c0134 	BSC_obs_vlimit
+0x40c0130 	BSC_#76
+0x40c0134 	BSC_#77
 0x40c0138 	BSC_mincore
 0x40c013c 	BSC_getgroups
 0x40c0140 	BSC_setgroups
@@ -524,10 +618,10 @@
 0x40c0148 	BSC_setpgid
 0x40c014c 	BSC_setitimer
 0x40c0150 	BSC_old_wait
-0x40c0154 	BSC_swapon
+0x40c0154 	BSC_obs_swapon
 0x40c0158 	BSC_getitimer
-0x40c015c 	BSC_old_gethostname
-0x40c0160 	BSC_old_sethostname
+0x40c015c 	BSC_obs_gethostname
+0x40c0160 	BSC_obs_sethostname
 0x40c0164 	BSC_getdtablesize
 0x40c0168 	BSC_dup2
 0x40c016c 	BSC_#91
@@ -538,7 +632,7 @@
 0x40c0180 	BSC_setpriority
 0x40c0184 	BSC_socket
 0x40c0188 	BSC_connect
-0x40c018c 	BSC_old_accept
+0x40c018c 	BSC_obs_accept
 0x40c0190 	BSC_getpriority
 0x40c0194 	BSC_old_send
 0x40c0198 	BSC_old_recv
@@ -546,15 +640,15 @@
 0x40c01a0 	BSC_bind
 0x40c01a4 	BSC_setsockopt
 0x40c01a8 	BSC_listen
-0x40c01ac 	BSC_obs_vtimes
-0x40c01b0 	BSC_old_sigvec
-0x40c01b4 	BSC_old_sigblock
-0x40c01b8 	BSC_old_sigsetmask
+0x40c01ac 	BSC_#107
+0x40c01b0 	BSC_obs_sigvec
+0x40c01b4 	BSC_obs_sigblock
+0x40c01b8 	BSC_obs_sigsetmask
 0x40c01bc 	BSC_sigsuspend
-0x40c01c0 	BSC_old_sigstack
-0x40c01c4 	BSC_old_recvmsg
-0x40c01c8 	BSC_old_sendmsg
-0x40c01cc 	BSC_obs_vtrace
+0x40c01c0 	BSC_obs_sigstack
+0x40c01c4 	BSC_obs_recvmsg
+0x40c01c8 	BSC_obs_sendmsg
+0x40c01cc 	BSC_#115
 0x40c01d0 	BSC_gettimeofday
 0x40c01d4 	BSC_getrusage
 0x40c01d8 	BSC_getsockopt
@@ -564,12 +658,12 @@
 0x40c01e8 	BSC_settimeofday
 0x40c01ec 	BSC_fchown
 0x40c01f0 	BSC_fchmod
-0x40c01f4 	BSC_old_recvfrom
-0x40c01f8 	BSC_old_setreuid
-0x40c01fc 	BSC_old_setregid
+0x40c01f4 	BSC_obs_recvfrom
+0x40c01f8 	BSC_obs_setreuid
+0x40c01fc 	BSC_obs_setregid
 0x40c0200 	BSC_rename
-0x40c0204 	BSC_old_truncate
-0x40c0208 	BSC_old_ftruncate
+0x40c0204 	BSC_obs_truncate
+0x40c0208 	BSC_obs_ftruncate
 0x40c020c 	BSC_flock
 0x40c0210 	BSC_mkfifo
 0x40c0214 	BSC_sendto
@@ -578,66 +672,66 @@
 0x40c0220 	BSC_mkdir
 0x40c0224 	BSC_rmdir
 0x40c0228 	BSC_utimes
-0x40c022c 	BSC_#139
+0x40c022c 	BSC_futimes
 0x40c0230 	BSC_adjtime
-0x40c0234 	BSC_old_getpeername
-0x40c0238 	BSC_old_gethostid
-0x40c023c 	BSC_old_sethostid
-0x40c0240 	BSC_old_getrlimit
-0x40c0244 	BSC_old_setrlimit
-0x40c0248 	BSC_old_killpg
+0x40c0234 	BSC_obs_getpeername
+0x40c0238 	BSC_obs_gethostid
+0x40c023c 	BSC_#143
+0x40c0240 	BSC_obs_getrlimit
+0x40c0244 	BSC_obs_setrlimit
+0x40c0248 	BSC_obs_killpg
 0x40c024c 	BSC_setsid
-0x40c0250 	BSC_obs_setquota
-0x40c0254 	BSC_obs_quota
-0x40c0258 	BSC_old_getsockname
-0x40c025c 	BSC_#151
+0x40c0250 	BSC_#148
+0x40c0254 	BSC_#149
+0x40c0258 	BSC_obs_getsockname
+0x40c025c 	BSC_getpgid
 0x40c0260 	BSC_setprivexec
-0x40c0264 	BSC_#153
-0x40c0268 	BSC_#154
+0x40c0264 	BSC_pread
+0x40c0268 	BSC_pwrite
 0x40c026c 	BSC_nfssvc
 0x40c0270 	BSC_getdirentries
 0x40c0274 	BSC_statfs
 0x40c0278 	BSC_fstatfs
 0x40c027c 	BSC_unmount
-0x40c0280 	BSC_obs_async_daemon
+0x40c0280 	BSC_#160
 0x40c0284 	BSC_getfh
-0x40c0288 	BSC_old_getdomainname
-0x40c028c 	BSC_old_setdomainname
-0x40c0290 	BSC_obs_pcfs_mount
+0x40c0288 	BSC_obs_getdomainname
+0x40c028c 	BSC_obs_setdomainname
+0x40c0290 	BSC_#164
 0x40c0294 	BSC_quotactl
-0x40c0298 	BSC_obs_exportfs
+0x40c0298 	BSC_#166
 0x40c029c 	BSC_mount
-0x40c02a0 	BSC_obs_ustat
+0x40c02a0 	BSC_#168
 0x40c02a4 	BSC_#169
-0x40c02a8 	BSC_obs_table
-0x40c02ac 	BSC_old_wait_3
-0x40c02b0 	BSC_obs_rpause
+0x40c02a8 	BSC_#170
+0x40c02ac 	BSC_obs_wait3
+0x40c02b0 	BSC_#172
 0x40c02b4 	BSC_#173
-0x40c02b8 	BSC_obs_getdents
+0x40c02b8 	BSC_#174
 0x40c02bc 	BSC_#175
 0x40c02c0 	BSC_add_profil
 0x40c02c4 	BSC_#177
 0x40c02c8 	BSC_#178
 0x40c02cc 	BSC_#179
-0x40c02d0 	BSC_kdebug
+0x40c02d0 	BSC_kdebug_trace
 0x40c02d4 	BSC_setgid
 0x40c02d8 	BSC_setegid
 0x40c02dc 	BSC_seteuid
-0x40c02e0 	BSC_lfs_bmapv
-0x40c02e4 	BSC_lfs_markv
-0x40c02e8 	BSC_lfs_segclean
-0x40c02ec 	BSC_lfs_segwait
+0x40c02e0 	BSC_#184
+0x40c02e4 	BSC_#185
+0x40c02e8 	BSC_#186
+0x40c02ec 	BSC_#187
 0x40c02f0 	BSC_stat
 0x40c02f4 	BSC_fstat
 0x40c02f8 	BSC_lstat
 0x40c02fc 	BSC_pathconf
 0x40c0300 	BSC_fpathconf
-0x40c0304 	BSC_getfsstat
+0x40c0304 	BSC_obs_getfsstat
 0x40c0308 	BSC_getrlimit
 0x40c030c 	BSC_setrlimit
 0x40c0310 	BSC_getdirentries
 0x40c0314 	BSC_mmap
-0x40c0318 	BSC___syscall
+0x40c0318 	BSC_#198
 0x40c031c 	BSC_lseek
 0x40c0320 	BSC_truncate
 0x40c0324 	BSC_ftruncate
@@ -655,18 +749,18 @@
 0x40c0354 	BSC_#213
 0x40c0358 	BSC_#214
 0x40c035c 	BSC_#215
-0x40c0360 	BSC_mkcomplex
-0x40c0364 	BSC_statv
-0x40c0368 	BSC_lstatv
-0x40c036c 	BSC_fstatv
+0x40c0360 	BSC_#216
+0x40c0364 	BSC_#217
+0x40c0368 	BSC_#218
+0x40c036c 	BSC_#219
 0x40c0370 	BSC_getattrlist
 0x40c0374 	BSC_setattrlist
 0x40c0378 	BSC_getdirentriesattr
 0x40c037c 	BSC_exchangedata
 0x40c0380 	BSC_checkuseraccess
 0x40c0384 	BSC_searchfs
-0x40c0388 	BSC_#226
-0x40c038c 	BSC_#227
+0x40c0388 	BSC_delete
+0x40c038c 	BSC_copyfile
 0x40c0390 	BSC_#228
 0x40c0394 	BSC_#229
 0x40c0398 	BSC_#230
@@ -681,7 +775,7 @@
 0x40c03bc 	BSC_#239
 0x40c03c0 	BSC_#240
 0x40c03c4 	BSC_#241
-0x40c03c8 	BSC_#242
+0x40c03c8 	BSC_fsctl
 0x40c03cc 	BSC_#243
 0x40c03d0 	BSC_#244
 0x40c03d4 	BSC_#245
@@ -737,7 +831,7 @@
 0x40c049c 	BSC_#295
 0x40c04a0 	BSC_load_shared_file
 0x40c04a4 	BSC_reset_shared_file
-0x40c04a8 	BSC_#298
+0x40c04a8 	BSC_new_system_shared_regions
 0x40c04ac 	BSC_#299
 0x40c04b0 	BSC_#300
 0x40c04b4 	BSC_#301
@@ -749,7 +843,7 @@
 0x40c04cc 	BSC_#307
 0x40c04d0 	BSC_#308
 0x40c04d4 	BSC_#309
-0x40c04d8 	BSC_#310
+0x40c04d8 	BSC_getsid
 0x40c04dc 	BSC_#311
 0x40c04e0 	BSC_#312
 0x40c04e4 	BSC_#313
@@ -765,6 +859,30 @@
 0x40c050c 	BSC_#323
 0x40c0510 	BSC_mlockall
 0x40c0514 	BSC_munlockall
+0x40c0518 	BSC_#326
+0x40c051c 	BSC_issetugid
+0x40c0520 	BSC_pthread_kill
+0x40c0524 	BSC_pthread_sigmask
+0x40c0528 	BSC_sigwait
+0x40c052c 	BSC_#331
+0x40c0530 	BSC_#332
+0x40c0534 	BSC_#333
+0x40c0538 	BSC_#334
+0x40c053c 	BSC_utrace
+0x40c0540 	BSC_#336
+0x40c0544 	BSC_#337
+0x40c0548 	BSC_#338
+0x40c054c 	BSC_#339
+0x40c0550 	BSC_#340
+0x40c0554 	BSC_#341
+0x40c0558 	BSC_#342
+0x40c055c 	BSC_#343
+0x40c0560 	BSC_#344
+0x40c0564 	BSC_#345
+0x40c0568 	BSC_#346
+0x40c056c 	BSC_#347
+0x40c0570 	BSC_#348
+0x40c0574 	BSC_#349
 0x50b0018  	IES_action
 0x50b001c  	IES_filter
 0x50c0010 	TES_action
diff --git a/sysctl.tproj/Makefile.postamble b/sysctl.tproj/Makefile.postamble
index 70b747f..f5f7c67 100644
--- a/sysctl.tproj/Makefile.postamble
+++ b/sysctl.tproj/Makefile.postamble
@@ -107,3 +107,7 @@
 # Makefile API), which are rules that get invoked before and after the install 
 # target runs.  Such rules should be specified with the '::' syntax rather than 
 # a single colon.
+
+after_install:
+	mkdir -p "$(DSTROOT)/usr/share/man/man8"
+	install -c -m 644 sysctl.8 "$(DSTROOT)/usr/share/man/man8/sysctl.8"
diff --git a/sysctl.tproj/Makefile.preamble b/sysctl.tproj/Makefile.preamble
index e371f9d..3a44cfd 100644
--- a/sysctl.tproj/Makefile.preamble
+++ b/sysctl.tproj/Makefile.preamble
@@ -111,3 +111,4 @@ OTHER_HELP_DIRS =
 # $(NAME).%d[.%d][.%d] and the following line must be uncommented.
 OTHER_GENERATED_OFILES = $(VERS_OFILE)
 
+AFTER_INSTALL = after_install
diff --git a/sysctl.tproj/sysctl.8 b/sysctl.tproj/sysctl.8
index bc348a9..b5151c1 100644
--- a/sysctl.tproj/sysctl.8
+++ b/sysctl.tproj/sysctl.8
@@ -93,7 +93,7 @@ purpose programs such as
 .Nm systat ,
 and
 .Nm netstat .
-The string and integer information is summaried below.
+The string and integer information is summarized below.
 For a detailed description of these variable see
 .Xr sysctl 3 .
 The changeable column indicates whether a process with appropriate
diff --git a/sysctl.tproj/sysctl.c b/sysctl.tproj/sysctl.c
index fb0dbb4..b1b8e75 100644
--- a/sysctl.tproj/sysctl.c
+++ b/sysctl.tproj/sysctl.c
@@ -346,6 +346,7 @@ old_parse(string, flags)
 		break;
 
 	case CTL_HW:
+		useUnsignedInt = 1;
 		break;
 
 	case CTL_VM:
@@ -887,10 +888,11 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind)
 static int
 show_var(int *oid, int nlen)
 {
-	u_char buf[BUFSIZ], *val, *p;
+	u_char buf[BUFSIZ], *val, *mval, *p;
 	char name[BUFSIZ], /* descr[BUFSIZ], */ *fmt;
 	int qoid[CTL_MAXNAME+2];
 	int i;
+	int retval;
 	size_t j, len;
 	u_int kind;
 	int (*func)(int, void *) = 0;
@@ -909,15 +911,18 @@ show_var(int *oid, int nlen)
 	i = sysctl(oid, nlen, 0, &j, 0, 0);
 	j += j; /* we want to be sure :-) */
 
-	val = alloca(j);
+	val = mval = malloc(j);
 	len = j;
 	i = sysctl(oid, nlen, val, &len, 0, 0);
-	if (i || !len)
-		return (1);
+	if (i || !len) {
+		retval = 1;
+		goto RETURN;
+	}
 
 	if (bflag) {
 		fwrite(val, 1, len, stdout);
-		return (0);
+		retval = 0;
+		goto RETURN;
 	}
 
 	qoid[1] = 4;
@@ -936,7 +941,8 @@ show_var(int *oid, int nlen)
 		if (!nflag)
 			printf("%s: ", name);
 		printf("%s", p);
-		return (0);
+		retval = 0;
+		goto RETURN;
 		
 	case 'I':
 		if (!nflag)
@@ -952,7 +958,8 @@ show_var(int *oid, int nlen)
 			len -= sizeof (int);
 			p += sizeof (int);
 		}
-		return (0);
+		retval = 0;
+		goto RETURN;
 
 	case 'L':
 		if (!nflag)
@@ -968,13 +975,15 @@ show_var(int *oid, int nlen)
 			len -= sizeof (long);
 			p += sizeof (long);
 		}
-		return (0);
+		retval = 0;
+		goto RETURN;
 
 	case 'P':
 		if (!nflag)
 			printf("%s: ", name);
 		printf("%p", *(void **)p);
-		return (0);
+		retval = 0;
+		goto RETURN;
 
 	case 'T':
 	case 'S':
@@ -986,12 +995,15 @@ show_var(int *oid, int nlen)
 		if (func) {
 			if (!nflag)
 				printf("%s: ", name);
-			return ((*func)(len, p));
+			retval = (*func)(len, p);
+			goto RETURN;
 		}
 		/* FALL THROUGH */
 	default:
-		if (!Aflag)
-			return (1);
+		if (!Aflag) {
+			retval = 1;
+			goto RETURN;
+		}
 		if (!nflag)
 			printf("%s: ", name);
 		printf("Format:%s Length:%ld Dump:0x", fmt, len);
@@ -1002,9 +1014,14 @@ show_var(int *oid, int nlen)
 			printf("...");
 			break;
 		}
-		return (0);
+		retval = 0;
+		goto RETURN;
 	}
-	return (1);
+
+	retval = 1;
+	RETURN:
+	free(mval);
+	return (retval);
 }
 
 static int
diff --git a/top.tproj/Makefile b/top.tproj/Makefile
index aa66116..b9c6003 100644
--- a/top.tproj/Makefile
+++ b/top.tproj/Makefile
@@ -23,7 +23,7 @@ MAKEFILE = tool.make
 NEXTSTEP_INSTALLDIR = /usr/bin
 WINDOWS_INSTALLDIR = /Library/Executables
 PDO_UNIX_INSTALLDIR = /usr/bin
-LIBS = 
+LIBS = -lcurses
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
diff --git a/top.tproj/top.c b/top.tproj/top.c
index d4dd628..f1755f1 100644
--- a/top.tproj/top.c
+++ b/top.tproj/top.c
@@ -69,6 +69,7 @@
 #include <mach/vm_map.h>
 #include <mach/vm_types.h>
 #include <mach/vm_prot.h>
+#include <mach/shared_memory_server.h>
 
 #include <device/device_types.h>
 #include <CoreFoundation/CoreFoundation.h>
@@ -82,7 +83,8 @@
 
 #include <libc.h>
 #include <termios.h>
-#include <bsd/curses.h>
+#include <curses.h>
+#include <sys/ioctl.h>
 
 /* Number of lines of header information on the standard screen */
 #define	HEADER_LINES	8
@@ -120,7 +122,6 @@ int werase(WINDOW *win);
 int total_threads;
 unsigned long long total_fw_private;
 
-struct termios tmode, omode;
 char   bytesread[128];
 
 host_cpu_load_info_data_t lastcounters, curcounters, startcounters;
@@ -228,10 +229,6 @@ struct object_info      *shared_hash_table[OBJECT_TABLE_SIZE];
 
 struct object_info *of_free_list = 0;
 
-#define FW_CODE_BEG_ADDR  0x70000000
-#define FW_DATA_BEG_ADDR  0x80000000
-#define FW_DATA_END_ADDR  0x90000000
-
 /*
  *	Translate thread state to a number in an ordered scale.
  *	When collapsing all the threads' states to one for the
@@ -451,7 +448,7 @@ pmem_doit(task_port_t task, int pid, int *shared, int *private, int *aliased, in
 				    &count, &object_name))
 		        break;
 
-		if (address >= FW_CODE_BEG_ADDR && address < FW_DATA_END_ADDR) {
+		if (address >= GLOBAL_SHARED_TEXT_SEGMENT && address < (GLOBAL_SHARED_DATA_SEGMENT + SHARED_DATA_REGION_SIZE)) {
 
 			*fw_private += info.private_pages_resident * vm_page_size;
 
@@ -529,13 +526,13 @@ pmem_doit(task_port_t task, int pid, int *shared, int *private, int *aliased, in
 		}
 	}
 	if (split)
-	        *vsize -= (FW_DATA_END_ADDR - FW_CODE_BEG_ADDR);
+	        *vsize -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE);
 }
 
 
 void
 pmem_fw_resident(unsigned int *num_fw, unsigned long long *vsize, unsigned int *code_size, unsigned int *data_size, unsigned int *linkedit_size)
-{       vm_address_t	address = FW_CODE_BEG_ADDR;
+{       vm_address_t	address = GLOBAL_SHARED_TEXT_SEGMENT;
 	kern_return_t	err = 0;
 	int             state = 0;
 
@@ -545,7 +542,7 @@ pmem_fw_resident(unsigned int *num_fw, unsigned long long *vsize, unsigned int *
         *data_size = 0;
         *linkedit_size = 0;
 
-	while (address < FW_DATA_END_ADDR) {
+	while (address < (GLOBAL_SHARED_DATA_SEGMENT + SHARED_DATA_REGION_SIZE)) {
 	        vm_region_submap_info_data_64_t   s_info;
 		mach_msg_type_number_t         count;
 	        vm_size_t	size;
@@ -557,9 +554,9 @@ pmem_fw_resident(unsigned int *num_fw, unsigned long long *vsize, unsigned int *
 		if (err = vm_region_recurse_64(mach_task_self(), &address, &size, &nesting_depth, (vm_region_info_t)&s_info, &count))
 		        break;
 
-		if (address >= FW_DATA_END_ADDR)
+		if (address >= (GLOBAL_SHARED_DATA_SEGMENT + SHARED_DATA_REGION_SIZE))
 		        break;
-		if (address < FW_DATA_BEG_ADDR) {
+		if (address < GLOBAL_SHARED_DATA_SEGMENT) {
 
 			if (s_info.share_mode == SM_SHARED || s_info.share_mode == SM_COW) {
 			        if (s_info.max_protection & VM_PROT_EXECUTE) {
@@ -884,8 +881,6 @@ void leave()			/* exit under normal conditions -- INT handler */
 	        move(LINES - 1, 0);
 		refresh();
 		endwin();
-
-		tcsetattr(0, TCSANOW, &omode);
 	}
 	exit(0);
 }
@@ -893,10 +888,8 @@ void leave()			/* exit under normal conditions -- INT handler */
 void quit(status)		/* exit under duress */
 	int status;
 {
-        if (!oneshot) {
+        if (!oneshot)
 	        endwin();
-		tcsetattr(0, TCSANOW, &omode);
-	}
 	exit(status);
 }
 
@@ -1313,22 +1306,10 @@ main(argc, argv)
 	/* initializes curses and screen (last) */
 
 	if (!oneshot) {
-	        if (tcgetattr(0, &tmode) < 0) {
-		        printf("can't get terminal attributes\n");
-			exit(1);
-		}
-		omode = tmode;
-	
-		tmode.c_lflag &= ~ICANON;
-		tmode.c_cc[VMIN] = 0;
-		tmode.c_cc[VTIME] = (delay * 10);
-
-		if (tcsetattr(0, TCSANOW, &tmode) < 0) {
-		        printf("can't set terminal attributes\n");
-			exit(1);
-		}
 		initscr();
-		refresh();
+		cbreak();
+		timeout(delay * 1000);
+		noecho();
 		erase();
 		clear();
 		refresh();
@@ -1387,12 +1368,16 @@ main(argc, argv)
 	        int   n;
 
 	        if (newLINES) {
+		        newLINES = 0;
 
 		        if (!oneshot) {
-			        initscr();
-				erase();
-				clear();
-				refresh();
+				struct winsize size;
+
+				if (ioctl(1, TIOCGWINSZ, &size) != -1) {
+					resizeterm(size.ws_row, size.ws_col);
+					erase();
+					clear();
+				}
 			}
 		        n = LINES - Header_lines;
 
@@ -1408,19 +1393,14 @@ main(argc, argv)
 					        topn = n;
 				}
 			}
-		        newLINES = 0;
 		}
 		(void)screen_update();
 
 		if (!oneshot) {
+			int	c;
 
-		        if ((n = read(0, &bytesread, 128)) > 0) {
-			        int   i;
-
-				for (i = 0; i < n; i++)
-				        if (bytesread[i] == 'q')
-					        leave();
-			}
+			if ((c = getch()) != ERR && (char)c == 'q') 
+				leave();
 		} else
 		        sleep(delay);
 	}
@@ -2241,11 +2221,12 @@ getDISKcounters()
                                                             (CFMutableDictionaryRef *) &properties,
 	                                                    kCFAllocatorDefault,
 	                                                    kNilOptions);
+                if (properties) {
 
-		/* Obtain the statistics from the drive properties */
-	        statistics = (CFDictionaryRef) CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey));
+                    /* Obtain the statistics from the drive properties */
+                    statistics = (CFDictionaryRef) CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey));
 
-		if (statistics) {
+                    if (statistics) {
 			/* Obtain the number of bytes read from the drive statistics */
 			number = (CFNumberRef) CFDictionaryGetValue (statistics,
 								     CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey));
@@ -2275,10 +2256,11 @@ getDISKcounters()
 				status = CFNumberGetValue(number, kCFNumberSInt64Type, &value);
 				totalWriteBytes += value;
 			}
-		}
-		/* Release resources */
+                    }
+                    /* Release resources */
 
-		CFRelease(properties); properties = 0;
+                    CFRelease(properties); properties = 0;
+                }
 		IOObjectRelease(drive); drive = 0;
 	}
 	IOIteratorReset(drivelist);
diff --git a/update.tproj/Makefile.postamble b/update.tproj/Makefile.postamble
index 70b747f..0e58184 100644
--- a/update.tproj/Makefile.postamble
+++ b/update.tproj/Makefile.postamble
@@ -107,3 +107,7 @@
 # Makefile API), which are rules that get invoked before and after the install 
 # target runs.  Such rules should be specified with the '::' syntax rather than 
 # a single colon.
+
+after_install:
+	mkdir -p "$(DSTROOT)/usr/share/man/man8"
+	install -c -m 644 update.8 "$(DSTROOT)/usr/share/man/man8/update.8"
diff --git a/update.tproj/Makefile.preamble b/update.tproj/Makefile.preamble
index e371f9d..3a44cfd 100644
--- a/update.tproj/Makefile.preamble
+++ b/update.tproj/Makefile.preamble
@@ -111,3 +111,4 @@ OTHER_HELP_DIRS =
 # $(NAME).%d[.%d][.%d] and the following line must be uncommented.
 OTHER_GENERATED_OFILES = $(VERS_OFILE)
 
+AFTER_INSTALL = after_install
diff --git a/vm_stat.tproj/Makefile b/vm_stat.tproj/Makefile
index 4b21a74..943af74 100644
--- a/vm_stat.tproj/Makefile
+++ b/vm_stat.tproj/Makefile
@@ -15,7 +15,7 @@ PROJECT_TYPE = Tool
 CFILES = vm_stat.c
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
-            h.template
+            h.template vm_stat.1
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
diff --git a/vm_stat.tproj/Makefile.postamble b/vm_stat.tproj/Makefile.postamble
index 411cde6..ee7c567 100644
--- a/vm_stat.tproj/Makefile.postamble
+++ b/vm_stat.tproj/Makefile.postamble
@@ -98,3 +98,6 @@
 # owned by the top-level Makefile API and no context has been set up for where 
 # derived files should go.
 #
+after_install:
+	install -d $(DSTROOT)/usr/share/man/man1
+	install -c -m 444 vm_stat.1 $(DSTROOT)/usr/share/man/man1
diff --git a/vm_stat.tproj/vm_stat.1 b/vm_stat.tproj/vm_stat.1
new file mode 100644
index 0000000..4ce6212
--- /dev/null
+++ b/vm_stat.tproj/vm_stat.1
@@ -0,0 +1,60 @@
+.\" Copyright (c) 1997, Apple Computer, Inc.  All rights reserved.
+.\"
+.Dd August 13, 1997
+.Dt VM_STAT 1
+.Os Mac OS X
+.Sh NAME
+.Nm vm_stat
+.Nd show Mach virtual memory statistics
+.Sh SYNOPSIS
+.Nm vm_stat
+.Op Ar interval
+.Sh DESCRIPTION
+.Nm vm_stat 
+displays Mach virtual memory statistics.  If the optional 
+.Ar interval 
+is specified, then 
+.Nm vm_stat 
+will display the statistics every 
+.Ar interval 
+seconds.  In this case, each line of output displays the change in
+each statistic (an
+.Ar interval 
+count of 1 displays the values per second).  However, the first line
+of output following each banner displays the system-wide totals for
+each statistic.  The following values are displayed:
+.Bl -tag -width indent -compact
+.It Pages free
+the total number of free pages in the system.
+.It Pages active
+the total number of pages currently in use and pageable.
+.It Pages inactive
+the total number of pages on the inactive list.
+.It Pages wired down
+the total number of pages wired down.  That is, pages that cannot be
+paged out.
+.It Translation faults
+the number of times the "vm_fault" routine has been called.
+.It Pages copy-on-write
+the number of faults that caused a page to be
+copied (generally caused by copy-on-write faults).
+.It Pages zero filled
+the total number of pages that have been zero-filled on demand.
+.It Pages reactivated
+the total number of pages that have been moved from the inactive list
+to the active list (reactivated).
+.It Pageins
+the number of requests for pages from a pager (such as the inode pager).
+.It Pageouts
+the number of pages that have been paged out.
+.Pp
+If 
+.Ar interval 
+is not specified, then 
+.Nm vm_stat 
+displays all accumulated statistics along with the page size and the
+object cache performance.
+
+
+.Sh SEE ALSO
+.Xr vm_statistics 2
diff --git a/zic.tproj/HACK/CST6CDT b/zic.tproj/HACK/CST6CDT
index 7ffb1d8e28afd09b3260c5f56595d5dd9ebd376e..1edb43c253f31b4bb24274c013bda6e9b39f8536 100644
GIT binary patch
delta 333
zcmaFI`JZ!wxF{<F0|N+yz-u4|u|+289A#GiQn2yE3#NJoM*NToNuHSniGyDov9bj1
zC)OZB>i+-Vxq*@4|Nqqs7+64T1`e=@Di4?vaCQk{a1IV(a0O!La3Br{0R<V*R1g6G
DC#@iu

delta 316
zcmey*`HpjfxF`z)0|N+yz$+jIu>~gT9NqZ!Ia56oBYwz?B+r1v#;=QL*?Q_5iPgma
m|95U+WcdGo^#TSKFq;EJGVn+^hlemY2LrK72!kt-h5-N*?i+Xj

diff --git a/zic.tproj/HACK/Cuba b/zic.tproj/HACK/Cuba
index 50fd5db0cc033c5d2c0037a9bae450e6d70c2cb3..d3350e326520a1e23b4f55a1341a0602ea973e13 100644
GIT binary patch
delta 508
zcmey&_M2^jxFjnB0|N+yz<eMEv3b@c9ctKUV9HqU5E)=9do{q!XhVS6-|Ybw(q}GM
zJiC0s^7pz6R>!tpu)aOvg3bC%0k*q~F4*;N39z3Xa={^gT7Y9qVStl=MSyckaDa<`
zRDi3CX@DEQO@O<Kc!2wlhzp*~KLb2(SY7aXd^^B<hs*_^Gv6=xPXBkoZ_UjM{^buY
z1oZ5_5SZ{cpgt&P?uB57`vD<7^%p`F4hDqjBwh$-SR4=`S{D%Upfw=!YeGQOf%Jgr
zt4;wiE1NIGZdD10>rA~6Kb0*YA=CXrVx7{3Bu~u?$#E<fQZ%_Qq}o2akS3%NkS=@T
zLi#7JfQ-MZE@WPO6OeVc=R)?za{)QWRtDrw+z^nrtUDmTaFT04L0fJ>Vbr<{MQQ#4
z#a0t8l(-oNlu8v{DAV`7Q1&b2LIuD6g^F8d7b@QiUZ~n7aiRL$=L<E9O#^DzUA<7(
zEFMtbxBbH84NO*(4=`~|e#OLF&%#Vy`2YW=0}KrR{~tfV$nyXH&J7G4FcKu<;Tyu>
R>;lBWA;5TLU}S_uH2{X~zEuDK

delta 499
zcmey(_L*&hxFib$0|N+yz<eMEv3b@c9h$Mxz?8AxT<(IYI{yVTafS=#Y#%R}e|vPn
z;@Ra3me-D4usXK&g7yA~0XFL|1=!9%9AMYKCBVLZX@Eoiv;fEW_5dgUiU4Q(%m5et
zr~p@a?*KP`n*eu?^b77kA})Bm@Vwx8!|H<93GEBsJ7g~Stl+)iJN@4UzxMYR{L3F)
z2q@$U2u%1JP#+ZVE+E+9en5!9g@90ng8^Xzn*zca76*iXm=X~2pfw=!LRmo6f%Jgr
zos%xatZcpzJG10MTxaTq_{y*g37PH}5+f}xBzbCHNVb%^kfO<bAywkfg)||JfOICw
zfb>sX0T~Z}2V`D+6OeWAZb0_Na{)OE_Xp%o+z^o0xG*5UaFT04LDt?2g;DD+6nV|R
zP;52fLWx%6g;J@a3uRo%7s`HxTqu9#dZFT$*@ene>KCeZNnEJj>=ID3*fgMavRXi0
zvv@##F-O4U4NO*(4=`~|e#OLF!^lis`2YW=6$}jj{~tfV$nyXH&J7G45Yodpgu&Sb
Mh=W5wQOgJ-01s@pN&o-=

diff --git a/zic.tproj/HACK/EST b/zic.tproj/HACK/EST
index 3961e6565c64ad60c80755558524f8e3d97afdf9..2d5f332abb11a2e8ec1a44e68184c80a5884f451 100644
GIT binary patch
delta 123
zcmeBWn#VLjT$GK0fdPa;KnaLJY>A0Fvdqd~3MP8w$T2W7F*7n?Ko&+8Rv?^sQOt;u
q=l}nm8yE!s|37|!QN-CLguyu&h{J(6AcVmc$aV#a0Rbb30FeNBR1{YL

delta 124
zcmbQo)XOwMT$Gi8fdPa;KoN*RY>|mNvJ-u?BbgW(7@062Gb1w#5dQzaa|0v8|NpBO
lFtC8x93YZ`=l}oX2N(sM!$TOHgMrv3guxX^y8>wh004L>8j1h_

diff --git a/zic.tproj/HACK/EST5EDT b/zic.tproj/HACK/EST5EDT
index 2ddcd429597596a11eec0ed36090b472b3171347..46d19f7304b485b2d4a970bec68c93ffe0ffc958 100644
GIT binary patch
delta 320
zcmaFF`I&QqxF`z)0|N+yz-u4|u>~gT9A#4evhn>(rg{cO;vo|=35tm`mL&U$GZMS1
o|NoC4U}X6Jf9D1U7BHIwOiJ>&x`Z&e1_N<85C?>S!if=t0m#xE6#xJL

delta 304
zcmey&`G|9ZxF|CN0|N+yz$+jIv3Vxy9NqZ!Ia56oBk_=d1hqt(T2Fl=v6}e*|M3Hi
d4FCV{+`zyBW^=fPhcLJX^8g8#5Kzbf0RV)=7fk>F

diff --git a/zic.tproj/HACK/Egypt b/zic.tproj/HACK/Egypt
index a084b0ab5346086537b634042275545401bc7ecf..6e3d7bf229b54dcbdc7f030ea5e941225020c879 100644
GIT binary patch
delta 240
zcmZ3@zMFl5xF8Dy0|N+yz&api*{I>hDEIAy#`9ebS`5`6v`*PKXg^$EptHJ|LHE$3
z4|+Yz8YcHJsxp5*A24|fkd7(7F!>InF7uLK0h4){LYc!<116_1=`zn-ePQwxCKZ-4
r_JDxNdzc#PnV4w-85pz-7=iAVQD9(2X1lruhcLLhh5)4)LGla$C^0LI

delta 125
zcmdnZzM6f4xF8b)0|N+yz&api+Nj~iDEH!l#`6gQS`4`lv`&czXg^$-ptIWJg6^R!
z5A=F!0w(t`sxrTta$)ioARTNOF!>InF7xdD7bf#Cg);lRx-dC~NtbzQVZh`mOe!p;
Y|3oiL-ow-|iP>fnv-ITo%wj<60L-r{Jpcdz

diff --git a/zic.tproj/HACK/Eire b/zic.tproj/HACK/Eire
index fab6a199383b6d18fd92633f7831c835c51dd4ea..6b51dd87c6f9705d6b43491406c025d623fea543 100644
GIT binary patch
delta 177
zcmZqWYUSE+khz|j2@Y9Vm<dBRRv;uo9oQsxPD}$iIFaFG2NnTF*2#e^d0cz~j4TWw
Uz%%(Ii;e&zki`fhz<`kv09QB(JOBUy

delta 177
zcmZqWYUSE+khz|Pi5Ui2SeXe!HWnZxLLJy7c1}zKIXIEwWCs=jMwZEeEO}fE3=BLB
W416H&NfsRe21W)3Mj(a&Mn(W>PYGxM

diff --git a/zic.tproj/HACK/Factory b/zic.tproj/HACK/Factory
index bc3e2e4d514869e0321729592888d1f8d0be92da..1be7c8e9a543c9953d51f194cbc9570d7e2344cb 100644
GIT binary patch
delta 24
fcmYd|ouJLAIZ;QMue3N-p`@xfwWPFwfq?-4U04Sq

delta 32
ncmaz|ouJKVI8jGgtT;7Qp(-<3AvZCvG%-h^ATd3afq?-4rRoW!

diff --git a/zic.tproj/HACK/HST b/zic.tproj/HACK/HST
index 47e56ddbe7b81d8353d090d1d0b58f4a7cf753ea..3e79673e1959836862d20e508a9068bbac207866 100644
GIT binary patch
literal 130
zcmZQzzzSG_q96<cY(NZR3+!ff_SmiPWXI`F+Y^_RzZ6_b^t8CzTkOHez{JeJ^8bHM
r1OvnW|5X``KsJ!%0Fylb{}(4PFn9!qFnG8CaX1hMgaD0WV1y6=OUE8_

literal 113
zcmZQzzzSG^q96<ctUwH6^Xz7I_SmiPWXI`F+Y^@(JuR;G7JD!<FflOy|DO}V!0`Wn
eRR$vqnB@5Xzc_(`!6P_?!NUcJ!$W}jApigY*%&hb

diff --git a/zic.tproj/HACK/Hongkong b/zic.tproj/HACK/Hongkong
index ad523a5a9577ae685702558312a5606670ab55b9..5f788c84f7671c72d4a69fd1267a1266dc88a6eb 100644
GIT binary patch
delta 78
zcmdnZyoz~(xF|CN0|N+yfGZG#*t{EcL>MOrFj`KIXXH_3V8~_x$<|F^1kwc!44gi`
PAq*bg!5|_8Bm)EhwFnD8

delta 92
zcmZ3*yqkG~xF`z)0|N+yfEy5l*n%5%L>O6&x8Gox?7--1#LU2u4OUV&fe}a-G%#?2
VNnRh{5C#wLU=R_);0&Z;004-)4gmlF

diff --git a/zic.tproj/HACK/Israel b/zic.tproj/HACK/Israel
index b604803358821b60e26c76234abb3cc1e8c786e6..08c0c58a98c20fbb29a604b89121cb6a8672b6f4 100644
GIT binary patch
delta 361
zcmV-v0ha!q1EU6zBLR+)B>8_avtTqD{?IiMm0&gTrcgHo2!J=w0dP3>Uw}E>`QSRx
z?QlD;TVOn+pm05)vS2=gf^a{4pWr}qHgG{uq+mi!fbc^-wO~Xov~Wcp=-@^U=kP}W
z9AHQBZ170pp<qeUpm0jV)Zk0A)9_5C2w+W>2XIb?JK#@ujBrqBz~FyTSikU6N%UY-
zIrDH-D<|Mp8z%5p3|nAU{j2a-?%-fp-rsOp&=cTVz!LCVu}5HBp+<0Bl6v4?gUfJV
zbpPOBWd87BRx@B?Mlx_?H)h~uCuQ(u7@A;a3F`1>`yXIu>mG1u+*06a%u(=ay@p_G
zt%Y!Gp1I&{kP2{afj&v#Z*e{FaAI;`aZ+(`azmxyb2FsybR^kebrvb`b_ZTycK2Oy
zcj%Gec-WBedCA3Kdbz}Kd#d>0e4I&eeT{wKetmrKe{Qj0lPm#1lTZO1lTZO1lTZN`
HlWYMo_Xn;%

delta 35
rcmZ3?HkWyVGNZ#pm7n|?6%R~2l><x#rzV(bvIa~}VRD%KiOCQE%}NVP

diff --git a/zic.tproj/HACK/Jamaica b/zic.tproj/HACK/Jamaica
index a77982e0a8c1993d144c1d8b1bdd8ea0fa8f094d..64be57cf3e652d96aeea5caee79fe1a2ad47b96d 100644
GIT binary patch
delta 20
ccmdnVxRY^$9_v;H4uyjgjZ+yJCeBm<07Q)jN&o-=

delta 20
ccmdnVxRY^$9_yAb?7fl`jZ+zUCeBm<08VcQ4FCWD

diff --git a/zic.tproj/HACK/Japan b/zic.tproj/HACK/Japan
index 5494fd200649d381afc02b94a00f3222878a38bf..6d77fe83a016fd07bcf04ff27156342ad9eceb64 100644
GIT binary patch
literal 73
scmZQzzzUdvq96<cj6e)xa~wX`S^(tKO#q1kNfu|X5C*T{5D=FE0DsX2i2wiq

literal 56
ecmZQzzzP_Fq96<dAT|pFL)`=h2Cv`{AO`>sVgd&M

diff --git a/zic.tproj/HACK/Libya b/zic.tproj/HACK/Libya
index 4ca7448f9478c520b13b7556687cec0c36427559..865e083e61b0b24d17abf938c9b7682b765a7aa3 100644
GIT binary patch
delta 62
zcmbQs`i^mexF8Dy0|N+yfGiNROw`EXG4lJEVC-U6U}Bo}VDcMANfu@%M&`*eOcIkD
Im_)&<0eATfA^-pY

delta 510
zcmaFIIG1&TxF8z?0|N+yKmic5P1MM#S7*z5pk9CIgJDej1S5ax3C6a&1xyV51x)4M
zO)wK|nqbbLBw+q&n}Efm<pP#htp%(O-<n{(EpLL&Qa%CO>5ByH+8ig?S6rRoka28+
zV|3I6C(mC3&Nh7lF50>iTxAbVaN|i7aQpXF!2R7b0gs1O0-hHnCwLuNJHdOSuYk|u
zhxG!!lNu)YwTeveFJ+w&kUn!lV3?&qkjGhpVDp>_AzBO*LM0XmgmIe)g#A_(2!Fd%
zAmUEMgvfJmCPeM+5s2QPAP_Te|Ag3y!4u*dT_(gA-<Xh)R3VTU$|I2Eym~^inf-(m
zmHPsz;>7}K>?s0iKYs|MznDHD<F@vM%#)`Dvi3y93uLeQHz8;4qzSpb%@gt(#3$tE
zZ5Jp=^cE=ee>I`Vscu5Cp`1X8@+N^&;l%=FY~})GU#?9kf1Wj=;u@Dg<%xL$RoiVR
zRIj`^p=Rcx3AH_86Y8qI3DoCy2~1od8P3SW%)&~2IB~CpCIf?v0wW6p1D^l`r;l$4
UgR^TehzMbD1!53jWCT+T06)>4Z2$lO

diff --git a/zic.tproj/HACK/MST b/zic.tproj/HACK/MST
index d684fb39956e69e6b7c1d5eb98391c0d965328e4..7dc48caa5cc055ddbdaa4f8ce6254fa25581d991 100644
GIT binary patch
delta 49
wcmZo-Y+{@cp~b|=#K^$-|NrU*j12$(&z-=)0%mjgx`Z(J1_N<;2m=HF0G~7tyZ`_I

delta 49
wcmZo-Y+{@cp~b++z{te-|NrU*j12$(&z-=)0%mjghKDft1_QB62m=HF0H1UYx&QzG

diff --git a/zic.tproj/HACK/MST7MDT b/zic.tproj/HACK/MST7MDT
index fc45907a08f34a2225e5557f3083d2dad235602d..889d6f05389dbc179b745aed8c6a4d438ba5553d 100644
GIT binary patch
delta 242
zcmcb^_LgmexF`z)0|N+yz+4~(u>~gTs4^>mDcBegz*Nt`$iT?N3?v2ydf~SA|Nqqs
j7#aTmpF4qp1<d9ElRUmIAq>93KpYOl0U;otF@i7v>M<D!

delta 225
zcmaFMc86_(xF|CN0|N+yz#Je3v3VxysBR4PXR2pnWMX6h;sJuTI4%DFfAs=JhX4QP
YPGDdGvpIajLl}I6f!HMk<P{(Q0E*TVwg3PC

diff --git a/zic.tproj/HACK/Navajo b/zic.tproj/HACK/Navajo
index fc45907a08f34a2225e5557f3083d2dad235602d..889d6f05389dbc179b745aed8c6a4d438ba5553d 100644
GIT binary patch
delta 242
zcmcb^_LgmexF`z)0|N+yz+4~(u>~gTs4^>mDcBegz*Nt`$iT?N3?v2ydf~SA|Nqqs
j7#aTmpF4qp1<d9ElRUmIAq>93KpYOl0U;otF@i7v>M<D!

delta 225
zcmaFMc86_(xF|CN0|N+yz#Je3v3VxysBR4PXR2pnWMX6h;sJuTI4%DFfAs=JhX4QP
YPGDdGvpIajLl}I6f!HMk<P{(Q0E*TVwg3PC

diff --git a/zic.tproj/HACK/PST8PDT b/zic.tproj/HACK/PST8PDT
index 458d9b7a0d7e026019bd911d8f536545252f29e2..c9ccbc1714b240e525e2e7ddbe8ae785e7831487 100644
GIT binary patch
delta 287
zcmaFC{*!%zxGoC=0|N+yz)m0ru?6NW^H?x{x9EfgZCVQ!&iX##bf?sUOUhpgHac8j
ys%K(mWEeo0MxN#W|IeMk$ngJve**&xn9Ttuc>-KQ7y^QUI2?!rLO{X52*LnQ5hPsz

delta 270
zcmey#{(^mixF$0L0|N+yzz!e=v3ce#^H?x{x9EfgZCVQ!&iX##bf?sUjV>3M>KPcB
n1`<Y+W%>XAb0;t|{QuwIz`z1#a|DEkFa!hxu}cWZ-#`EWVVfRq

diff --git a/zic.tproj/HACK/Poland b/zic.tproj/HACK/Poland
index c6ea4cd6bc64dc8586337531473337704f00fcc3..7fda6e6be233bb32ae3e8526f3f503f934e478c2 100644
GIT binary patch
delta 464
zcmZ3(evo~FxF8n;0|N+yz+xcg+NcrASl`3=!R&9nfQ9sw2^Mz~1uTD;O|aVQEMR>*
zVuH=G_zAYVttQyDIZm*jEi=I(O?iT2i=}{*8|wt;6lnn$)#npjo&O5Bv7VgZu6$p>
z{oOMGPv(OHp65;ocs*V$;Jt2@fX|uz6MXx61pL-4oZz3AClJunJRvZ=YeG;?>V#nP
zoC)<IKJF7j#r-CP>1a*}`))8HLexzl;=0g;$gdg#QQN*uh`!1t5VJr~Aa=_efw=n5
z0`XJM2_(c{6-caoH6h7<yFha6nF%TKGX+v@*G)*{*g7FycEW`87t<$X{4JW0d7^Sc
z*4>Z^*(;(a<Qyv$$nCJ5khd&YAU{KXLP49UKw+Sbtw2$lxInR?oIr`|Pk~ZF27xkt
z(FtWA9tl+NeV<Tq;fO%xyPFfLHY^jUKDT>9&CEj+YS+!3P*=HRLVaKTgvnc&Lj0LH
mIH?IIhcO%QFfhm{FtRW(@Ch(*PHtnC<6&e3#~YAfWCQ?1!js|v

delta 371
zcmX@ezJ`5*xF81u0|N+yz#<^#*r*Z8SpT<>!9u#N!QyT(gXQmx2CKcM4A!^38f=yY
zHrVdgX|QWEZm^%t*Wi#Q+Thrt&EVwvy}>z!m%&B#W`nEqdj>bw-3{)_7a82&-C*!!
z-pt^6ZWn{s<EaeZ>*g@{oY~mm+gHcnw`OvKe_jGZKu>8yV0cYKP)>M5uz6fVh>vAM
zeW<uYLzs?qL)dqvh6qs$hKTDd4Uu1^7^1d4Ylyz`haqMGGehi_dkk^)PZ{E;9AHR@
zKhBU?d#54EekDV4?7oH+`EG_(+XW429LpQhWt$q(UvxHP{7q@dJdxdyb=R#SdxdX9
z&aq^M+z$PQyk)Ko`5A%@1#RjKg@JkuMQNOt48?{53?;6w8A=5{F_h`EH<W$2!cf8Y
zvZ3O_HipV~ryHs^%wVWKx3-~X=9Y%qb^Q%>mD3vP`wAN-?_dg<{D4UZh?OQsGaF2v
K&MXHDUIqX+xr^%n

diff --git a/zic.tproj/HACK/Portugal b/zic.tproj/HACK/Portugal
index 84933f9aa3779995ac86991c089221bbbd0d9665..340fc401f7b1d391bcd9b343a25d556fec0fefa7 100644
GIT binary patch
delta 58
zcmey!`GIqSHly@LohlYhAqECM0R|u`qrfNzVl%QZfB>hDZwN!UYcPlaVc*FYSQG&`
Cj0&Lu

delta 59
zcmeys`H^#iHlxf&ohlYBVFm_10R|u`qrfN*Vl%QZfB>hDZwN!UYcPlaVVB^^=UEg1
DL*xqY

diff --git a/zic.tproj/HACK/W-SU b/zic.tproj/HACK/W-SU
index af292f7decb8dad7e80cef99fd42cebee0dbac28..38651468ac9724fa40287d4492995762de4313ae 100644
GIT binary patch
delta 271
zcmZ3)ww`T*xFHV%0|N+yKqC-?*mASu<!;Qi`!r*o)_aM0-z_`lw?s%RxRJ}TkU>mi
zqst4%dL~9DW=3XK7FIS^7IqdO4T2n;NRW%0gOvqYfSPOxP7VeJWet#<4Ko;7fb0km
p+rDD*9wuW`-w+1hU?6q@5y9R-?84yc8Un;X0T^He0vH=a0|3OxAg=%b

delta 232
zcmZ3_wuo(lxGpyX0|N+yKm!ni*m862K5dz&_1<LOcgrR7TW2p>a3fb`A%mF9MvoVa
z^$d(m3`{J{EUYZdY|KC!1lc)|ASV|)3p26+RoQ~<3=D=oj6i29+c2;&FxbaTKF(y!
V8XUsl>pS^BlRQ5o5CCOi005Sk8zKMz

diff --git a/zic.tproj/Makefile.postamble b/zic.tproj/Makefile.postamble
index 4db6c70..ead4ca7 100644
--- a/zic.tproj/Makefile.postamble
+++ b/zic.tproj/Makefile.postamble
@@ -191,10 +191,16 @@ right_posix: right_only other_two
 #	ln -s ${TZDIR}/${LOCALTIME} ${DSTROOT}/etc/localtime
 
 #since we are not doing native builds ... hack hack hack
+
+ZONE_FILES = africa antarctica asia australasia europe northamerica southamerica pacificnew etcetera factory backward systemv solar87 solar88 solar89
+
 after_install::
 	-mkdir -p ${DSTROOT}/usr/share
 	-rm -rf ${DSTROOT}/usr/share/zoneinfo
-	cp -r HACK ${DSTROOT}/usr/share/zoneinfo
+	mkdir -p ${DSTROOT}/usr/share/zoneinfo
+	for tz in $(ZONE_FILES); do \
+		zic -L /dev/null -d ${DSTROOT}/usr/share/zoneinfo -y datfiles/yearistype.sh datfiles/$${tz}; \
+	done
 	chmod -R og-w ${DSTROOT}/usr/share/zoneinfo
 	-mkdir -p ${DSTROOT}/private/etc
 	-rm -f ${DSTROOT}/private/etc/localtime
diff --git a/zic.tproj/datfiles/africa b/zic.tproj/datfiles/africa
index 1a601c9..6ce6106 100644
--- a/zic.tproj/datfiles/africa
+++ b/zic.tproj/datfiles/africa
@@ -1,17 +1,18 @@
-#	$OpenBSD: africa,v 1.4 1997/01/14 04:36:47 millert Exp $
-# @(#)africa	7.16
+# @(#)africa	7.34
+
+# $FreeBSD: src/share/zoneinfo/africa,v 1.12 2000/10/25 19:36:48 wollman Exp $
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
 # tz@elsie.nci.nih.gov for general use in the future).
 
-# From Paul Eggert <eggert@twinsun.com> (1996-11-22):
+# From Paul Eggert <eggert@twinsun.com> (1999-03-22):
 #
 # A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
+# Thomas G. Shanks, The International Atlas (5th edition),
+# San Diego: ACS Publications, Inc. (1999).
 #
-# Gwillim Law <LAW@encmail.encompass.com> writes that a good source
+# Gwillim Law <Gwil_Law@bridge-point.com> writes that a good source
 # for recent time zone data is the International Air Transport
 # Association's Standard Schedules Information Manual (IATA SSIM),
 # published semiannually.  Law sent in several helpful summaries
@@ -25,98 +26,42 @@
 # I found in the UCLA library.
 #
 # A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and the discovery of the longitude,
-# Oxford University Press (1980).
-#
-# I added so many Zone names that the old, mostly flat name space was unwieldy.
-# So I renamed the Zones to have the form AREA/LOCATION, where
-# AREA is the name of a continent or ocean, and
-# LOCATION is the name of a specific location within that region.
-# For example, the old zone name `Egypt' is now `Africa/Cairo'.
-#
-# Here are the general rules I used for choosing location names,
-# in decreasing order of importance:
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
-#	Use only valid Posix file names.  Use only Ascii letters, digits, `.',
-#		`-' and `_'.  Do not exceed 14 characters or start with `-'.
-#		E.g. prefer `Brunei' to `Bandar_Seri_Begawan'.
-#	Include at least one location per time zone rule set per country.
-#		One such location is enough.
-#	If all the clocks in a country's region have agreed since 1970,
-#		don't bother to include more than one location
-#		even if subregions' clocks disagreed before 1970.
-#		Otherwise these tables would become annoyingly large.
-#	If a name is ambiguous, use a less ambiguous alternative;
-#		e.g. many cities are named San Jose and Georgetown, so
-#		prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'.
-#	Keep locations compact.  Use cities or small islands, not countries
-#		or regions, so that any future time zone changes do not split
-#		locations into different time zones.  E.g. prefer `Paris'
-#		to `France', since France has had multiple time zones.
-#	Use traditional English spelling, e.g. prefer `Rome' to `Roma', and
-#		prefer `Athens' to the true name (which uses Greek letters).
-#		The Posix file name restrictions encourage this rule.
-#	Use the most populous among locations in a country's time zone,
-#		e.g. prefer `Shanghai' to `Beijing'.  Among locations with
-#		similar populations, pick the best-known location,
-#		e.g. prefer `Rome' to `Milan'.
-#	Use the singular form, e.g. prefer `Canary' to `Canaries'.
-#	Omit common suffixes like `_Islands' and `_City', unless that
-#		would lead to ambiguity.  E.g. prefer `Cayman' to
-#		`Cayman_Islands' and `Guatemala' to `Guatemala_City',
-#		but prefer `Mexico_City' to `Mexico' because the country
-#		of Mexico has several time zones.
-#	Use `_' to represent a space.
-#	Omit `.' from abbreviations in names, e.g. prefer `St_Helena'
-#		to `St._Helena'.
+# Previous editions of this database used WAT, CAT, SAT, and EAT
+# for +0:00 through +3:00, respectively,
+# but Mark R V Murray <markm@grondar.za> reports that
+# `SAST' is the official abbreviation for +2:00 in the country of South Africa,
+# `CAT' is commonly used for +2:00 in countries north of South Africa, and
+# `WAT' is probably the best name for +1:00, as the common phrase for
+# the area that includes Nigeria is ``West Africa''.
+# He has heard of ``Western Sahara Time'' for +0:00 but can find no reference.
 #
-# For time zone abbreviations like `EST' I used the following rules,
-# in decreasing order of importance:
+# To make things confusing, `WAT' seems to have been used for -1:00 long ago;
+# I'd guess that this was because people needed _some_ name for -1:00,
+# and at the time, far west Africa was the only major land area in -1:00.
+# This usage is now obsolete, as the last use of -1:00 on the African
+# mainland seems to have been 1976 in Western Sahara.
 #
-#	Use abbreviations that consist of 3 or more upper-case Ascii letters,
-#		except use "___" for locations while uninhabited.
-#		Posix.1 requires at least 3 characters, and the restriction to
-#		upper-case Ascii letters follows most traditions.
-#		Previous editions of this database also used characters like
-#		' ' and '?', but these characters have a special meaning to
-#		the shell and cause commands like
-#			set `date`
-#		to have unexpected effects.  In theory, the character set could
-#		be !%./@A-Z^_a-z{}, but these tables use only upper-case
-#		Ascii letters (and "___").
-#	Use abbreviations that are in common use among English-speakers,
-#		e.g. `EST' for Eastern Standard Time in North America.
-#		We assume that applications translate them to other languages
-#		as part of the normal localization process; for example,
-#		a French application might translate `EST' to `HNE'.
-#	For zones whose times are taken from a city's longitude, use the
-#		traditional xMT notation, e.g. `PMT' for Paris Mean Time.
-#		The only name like this in current use is `GMT'.
-#	If there is no common English abbreviation, abbreviate the English
-#		translation of the usual phrase used by native speakers.
-#		If this is not available or is a phrase mentioning the country
-#		(e.g. ``Cape Verde Time''), then:
+# To summarize, the following abbreviations seem to have some currency:
+#	-1:00	WAT	West Africa Time (no longer used)
+#	 0:00	GMT	Greenwich Mean Time
+#	 2:00	CAT	Central Africa Time
+#	 2:00	SAST	South Africa Standard Time
+# and Murray suggests the following abbreviation:
+#	 1:00	WAT	West Africa Time
+# I realize that this leads to `WAT' being used for both -1:00 and 1:00
+# for times before 1976, but this is the best I can think of
+# until we get more information.
 #
-#		When a country has a single or principal time zone region,
-#			append `T' to the country's ISO	code, e.g. `CVT' for
-#			Cape Verde Time.  For summer time append `ST';
-#			for double summer time append `DST'; etc.
-#		When a country has multiple time zones, take the first three
-#			letters of an English place name identifying each zone
-#			and then append `T', `ST', etc. as before;
-#			e.g. `MOSST' for MOScow Summer Time.
-#
-#
-# For Africa I invented the following time zone abbreviations.
-#		LMT	Local Mean Time
-#	-1:00	AAT	Atlantic Africa Time (no longer used)
-#	 0:00	WAT	West Africa Time
-#	 1:00	CAT	Central Africa Time
-#	 2:00	SAT	South Africa Time
+# I invented the following abbreviations; corrections are welcome!
+#	 2:00	WAST	West Africa Summer Time
+#	 2:30	BEAT	British East Africa Time (no longer used)
+#	 2:45	BEAUT	British East Africa Unified Time (no longer used)
+#	 3:00	CAST	Central Africa Summer Time (no longer used)
+#	 3:00	SAST	South Africa Summer Time (no longer used)
 #	 3:00	EAT	East Africa Time
-# The final `T' is replaced by `ST' for summer time, e.g. `SAST'.
-# BEAT is British East Africa Time, which was 2:30 before 1948 and 2:45 after.
-
+#	 4:00	EAST	East Africa Summer Time (no longer used)
 
 # Algeria
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -159,40 +104,37 @@ Zone	Africa/Algiers	0:12:12 -	LMT	1891 Mar 15 0:01
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Luanda	0:52:56	-	LMT	1892
 			0:52:04	-	LMT	1911 May 26 # Luanda Mean Time?
-			1:00	-	CAT
-
-# Bassas da India
-# uninhabited
+			1:00	-	WAT
 
 # Benin
 # Whitman says they switched to 1:00 in 1946, not 1934; go with Shanks.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Porto-Novo	0:10:28	-	LMT	1912
-			0:00	-	WAT	1934 Feb 26
-			1:00	-	CAT
+			0:00	-	GMT	1934 Feb 26
+			1:00	-	WAT
 
 # Botswana
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Gaborone	1:43:40 -	LMT	1885
-			2:00	-	SAT	1943 Sep 19 2:00
-			2:00	1:00	SAST	1944 Mar 19 2:00
-			2:00	-	SAT
+			2:00	-	CAT	1943 Sep 19 2:00
+			2:00	1:00	CAST	1944 Mar 19 2:00
+			2:00	-	CAT
 
 # Burkina Faso
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Ouagadougou	-0:06:04 -	LMT	1912
-			 0:00	-	WAT
+			 0:00	-	GMT
 
 # Burundi
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Bujumbura	1:57:28	-	LMT	1890
-			2:00	-	SAT
+			2:00	-	CAT
 
 # Cameroon
 # Whitman says they switched to 1:00 in 1920; go with Shanks.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Douala	0:38:48	-	LMT	1912
-			1:00	-	CAT
+			1:00	-	WAT
 
 # Cape Verde
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -205,29 +147,36 @@ Zone Atlantic/Cape_Verde -1:34:04 -	LMT	1907			# Praia
 # Central African Republic
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Bangui	1:14:20	-	LMT	1912
-			1:00	-	CAT
+			1:00	-	WAT
 
 # Chad
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Ndjamena	1:00:12 -	LMT	1912
-			1:00	-	CAT	1979 Oct 14
-			1:00	1:00	CAST	1980 Mar  8
-			1:00	-	CAT
+			1:00	-	WAT	1979 Oct 14
+			1:00	1:00	WAST	1980 Mar  8
+			1:00	-	WAT
 
 # Comoros
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Indian/Comoro	2:53:04 -	LMT	1911 Jul   # Moroni, Gran Comoro
 			3:00	-	EAT
 
-# Congo
+# Democratic Republic of Congo
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Kinshasa	1:01:12 -	LMT	1897 Nov 9
+			1:00	-	WAT
+Zone Africa/Lubumbashi	1:49:52 -	LMT	1897 Nov 9
+			2:00	-	CAT
+
+# Republic of the Congo
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Brazzaville	1:01:08 -	LMT	1912
-			1:00	-	CAT
+			1:00	-	WAT
 
 # Cote D'Ivoire
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Abidjan	-0:16:08 -	LMT	1912
-			 0:00	-	WAT
+			 0:00	-	GMT
 
 # Djibouti
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -238,18 +187,6 @@ Zone	Africa/Djibouti	2:52:36 -	LMT	1911 Jul
 
 # Egypt
 
-# From Bob Devine (1988-01-28):
-# Egypt: DST from first day of May to first of October (ending may
-# also be on Sept 30th not 31st -- you might want to ask one of the
-# soc.* groups, you might hit someone who could ask an embassy).
-# DST since 1960 except for 1981-82.
-
-# From U. S. Naval Observatory (1989-01-19):
-# EGYPT               2 H  AHEAD OF UTC
-# EGYPT               3 H  AHEAD OF UTC  MAY 17 - SEP 30 (AFTER
-# EGYPT                                  RAMADAN)
-
-# From Shanks (1991):
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Egypt	1940	only	-	Jul	15	0:00	1:00	S
 Rule	Egypt	1940	only	-	Oct	 1	0:00	0	-
@@ -264,16 +201,16 @@ Rule	Egypt	1957	1958	-	Oct	 1	0:00	0	-
 Rule	Egypt	1958	only	-	May	 1	0:00	1:00	S
 Rule	Egypt	1959	1981	-	May	 1	1:00	1:00	S
 Rule	Egypt	1959	1965	-	Sep	30	3:00	0	-
-Rule	Egypt	1966	1990	-	Oct	 1	3:00	0	-
+Rule	Egypt	1966	1994	-	Oct	 1	3:00	0	-
 Rule	Egypt	1982	only	-	Jul	25	1:00	1:00	S
 Rule	Egypt	1983	only	-	Jul	12	1:00	1:00	S
 Rule	Egypt	1984	1988	-	May	 1	1:00	1:00	S
 Rule	Egypt	1989	only	-	May	 6	1:00	1:00	S
-Rule	Egypt	1990	only	-	May	 1	1:00	1:00	S
-Rule	Egypt	1991	1994	-	May	 1	0:00	1:00	S
-Rule	Egypt	1991	1994	-	Oct	 1	0:00	0	-
-Rule	Egypt	1995	max	-	Apr	lastFri	0:00	1:00	S
-Rule	Egypt	1995	max	-	Sep	lastFri	0:00	0	-
+Rule	Egypt	1990	1994	-	May	 1	1:00	1:00	S
+# IATA (after 1990) says transitions are at 0:00.
+# Go with IATA starting in 1995, except correct 1995 entry from 09-30 to 09-29.
+Rule	Egypt	1995	max	-	Apr	lastFri	 0:00s	1:00	S
+Rule	Egypt	1995	max	-	Sep	lastThu	23:00s	0	-
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
@@ -282,113 +219,93 @@ Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
 # Equatorial Guinea
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Malabo	0:35:08 -	LMT	1912
-			0:00	-	WAT	1963 Dec 15
-			1:00	-	CAT
+			0:00	-	GMT	1963 Dec 15
+			1:00	-	WAT
 
 # Eritrea
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Asmera	2:35:32 -	LMT	1870
 			2:35:32	-	AMT	1890	      # Asmera Mean Time
-			2:35:20	-	AAMT	1936 May 5    # Addis Ababa MT?
+			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
 			3:00	-	EAT
 
 # Ethiopia
+# From Paul Eggert (1997-10-05):
+# Shanks writes that Ethiopia had six narrowly-spaced time zones between
+# 1870 and 1890, and that they merged to 38E50 (2:35:20) in 1890.
+# We'll guess that 38E50 is for Adis Dera.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Addis_Ababa	2:34:48 -	LMT	1870
-			2:35:20	-	AAMT	1936 May 5    # Addis Ababa MT?
+			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
 			3:00	-	EAT
 
-# Europa Island
-# uninhabited
-
 # Gabon
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Libreville	0:37:48 -	LMT	1912
-			1:00	-	CAT
+			1:00	-	WAT
 
 # Gambia
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Banjul	-1:06:36 -	LMT	1912
 			-1:06:36 -	BMT	1935	# Banjul Mean Time
-			-1:00	-	AAT	1964
-			 0:00	-	WAT
+			-1:00	-	WAT	1964
+			 0:00	-	GMT
 
 # Ghana
-# From Paul Eggert <eggert@twinsun.com> (1996-09-03):
-# WATST is my invention for ``West Africa one-Third Summer Time''.
-# From Shanks (1991):
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 # Whitman says DST was observed from 1931 to ``the present''; go with Shanks.
-Rule	Ghana	1936	1942	-	Sep	 1	0:00	0:20	WATST
-Rule	Ghana	1936	1942	-	Dec	31	0:00	0	WAT
+Rule	Ghana	1936	1942	-	Sep	 1	0:00	0:20	GHST
+Rule	Ghana	1936	1942	-	Dec	31	0:00	0	GMT
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Accra	-0:00:52 -	LMT	1918
 			 0:00	Ghana	%s
 
-# Glorioso Is
-# uninhabited
-
 # Guinea
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Conakry	-0:54:52 -	LMT	1912
-			 0:00	-	WAT	1934 Feb 26
-			 1:00	-	CAT	1960
-			 0:00	-	WAT
+			 0:00	-	GMT	1934 Feb 26
+			-1:00	-	WAT	1960
+			 0:00	-	GMT
 
 # Guinea-Bissau
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Bissau	-1:02:20 -	LMT	1911 May 26
-			 1:00	-	CAT	1975
-			 0:00	-	WAT
-
-# Juan de Nova
-# uninhabited
+			-1:00	-	WAT	1975
+			 0:00	-	GMT
 
 # Kenya
-# From Paul Eggert <eggert@twinsun.com> (1993-11-18):
-# Shanks says the transition to 2:45 was in 1940, but it must have been 1948.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Nairobi	2:27:16	-	LMT	1928 Jul
 			3:00	-	EAT	1930
-			2:30	-	BEAT	1948
-			2:45	-	BEAT	1960
+			2:30	-	BEAT	1940
+			2:45	-	BEAUT	1960
 			3:00	-	EAT
 
 # Lesotho
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Maseru	1:50:00 -	LMT	1903 Mar
-			2:00	-	SAT	1943 Sep 19 2:00
+			2:00	-	SAST	1943 Sep 19 2:00
 			2:00	1:00	SAST	1944 Mar 19 2:00
-			2:00	-	SAT
+			2:00	-	SAST
 
 # Liberia
 # From Paul Eggert <eggert@twinsun.com> (1993-11-18):
 # In 1972 Liberia was the last country to switch
-# from a GMT offset that was not a multiple of 15 minutes.
+# from a UTC offset that was not a multiple of 15 minutes.
 # Howse reports that it was in honor of their president's birthday.
 # Shanks reports the date as May 1, whereas Howse reports Jan; go with Shanks.
 # For Liberia before 1972, Shanks reports -0:44, whereas Howse and Whitman
 # each report -0:44:30; go with the more precise figure.
-#
-# From Shanks (1991), as corrected by Whitman:
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Monrovia	-0:43:08 -	LMT	1882
 			-0:43:08 -	MMT	1919 Mar # Monrovia Mean Time
 			-0:44:30 -	LRT	1972 May # Liberia Time
-			 0:00	-	WAT
+			 0:00	-	GMT
 
 ###############################################################################
 
 # Libya
 
-# From Bob Devine (January 28 1988):
-# Libya: Since 1982 April 1st to September 30th (?)
-
-# From U. S. Naval Observatory (1989-01-19):
-# LIBYAN ARAB         1 H  AHEAD OF UTC  JAMAHIRIYA/LIBYA
-# LIBYAN ARAB         2 H  AHEAD OF UTC  APR 1 - SEP 30 JAMAHIRIYA/LIBYA
-
-# From Shanks (1991):
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Libya	1951	only	-	Oct	14	2:00	1:00	S
 Rule	Libya	1952	only	-	Jan	 1	0:00	0	-
@@ -403,16 +320,17 @@ Rule	Libya	1986	only	-	Apr	 4	0:00	1:00	S
 Rule	Libya	1986	only	-	Oct	 3	0:00	0	-
 Rule	Libya	1987	1989	-	Apr	 1	0:00	1:00	S
 Rule	Libya	1987	1990	-	Oct	 1	0:00	0	-
-Rule	Libya	1990	only	-	May	 4	0:00	1:00	S
-Rule	Libya	1996	max	-	Mar	30	2:00s	1:00	S
-Rule	Libya	1996	max	-	Sep	30	2:00s	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Tripoli	0:52:44 -	LMT	1920
 			1:00	Libya	CE%sT	1959
 			2:00	-	EET	1982
-			1:00	Libya	CE%sT	1991
-			2:00	-	EET	1996 Mar 30 3:00
-			1:00	Libya	CE%sT
+			1:00	Libya	CE%sT	1990 May  4
+# The following entries are all from Shanks;
+# the IATA SSIM data contain some obvious errors.
+			2:00	-	EET	1996 Sep 30
+			1:00	-	CET	1997 Apr  4
+			1:00	1:00	CEST	1997 Oct  4
+			2:00	-	EET
 
 # Madagascar
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -424,24 +342,24 @@ Zone Indian/Antananarivo 3:10:04 -	LMT	1911 Jul
 # Malawi
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Blantyre	2:20:00 -	LMT	1903 Mar
-			2:00	-	SAT
+			2:00	-	CAT
 
 # Mali
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Bamako	-0:32:00 -	LMT	1912
-			 0:00	-	WAT	1934 Feb 26
-			-1:00	-	AAT	1960 Jun 20
-			 0:00	-	WAT
+			 0:00	-	GMT	1934 Feb 26
+			-1:00	-	WAT	1960 Jun 20
+			 0:00	-	GMT
 # no longer different from Bamako, but too famous to omit
 Zone	Africa/Timbuktu	-0:12:04 -	LMT	1912
-			 0:00	-	WAT
+			 0:00	-	GMT
 
 # Mauritania
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Nouakchott	-1:03:48 -	LMT	1912
-			 0:00	-	WAT	1934 Feb 26
-			-1:00	-	AAT	1960 Jun 20
-			 0:00	-	WAT
+			 0:00	-	GMT	1934 Feb 26
+			-1:00	-	WAT	1960 Nov 28
+			 0:00	-	GMT
 
 # Mauritius
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -456,6 +374,7 @@ Zone	Indian/Mayotte	3:00:56 -	LMT	1911 Jul	# Mamoutzou
 			3:00	-	EAT
 
 # Morocco
+# See the `europe' file for Spanish Morocco (Africa/Ceuta).
 # RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
 Rule	Morocco	1939	only	-	Nov	19	 0:00	0	-
@@ -479,68 +398,86 @@ Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
 			 0:00	-	WET
 # Western Sahara
 Zone Africa/El_Aaiun	-0:52:48 -	LMT	1934 Jan
-			-1:00	-	AAT	1976 Apr 14
+			-1:00	-	WAT	1976 Apr 14
 			 0:00	-	WET
 
 # Mozambique
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Maputo	2:10:20 -	LMT	1903 Mar
-			2:00	-	SAT
+			2:00	-	CAT
 
 # Namibia
+# The 1994-04-03 transition is from Shanks.
+# Shanks reports no DST after 1998-04; go with IATA.
 # RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Namibia	1994	max	-	Sep	Sun>=1	2:00	1:00	S
 Rule	Namibia	1995	max	-	Apr	Sun>=1	2:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Windhoek	1:08:24 -	LMT	1892 Feb 8
 			1:30	-	SWAT	1903 Mar	# SW Africa Time
-			2:00	-	SAT	1942 Sep 20 2:00
+			2:00	-	SAST	1942 Sep 20 2:00
 			2:00	1:00	SAST	1943 Mar 21 2:00
-			2:00	Namibia	SA%sT
+			2:00	-	SAST	1990 Mar 21 # independence
+			2:00	-	CAT	1994 Apr  3
+			1:00	Namibia	WA%sT
 
 # Niger
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Niamey	0:08:28 -	LMT	1912
-			1:00	-	CAT	1934 Feb 26
-			0:00	-	WAT	1960
-			1:00	-	CAT
+Zone	Africa/Niamey	 0:08:28 -	LMT	1912
+			-1:00	-	WAT	1934 Feb 26
+			 0:00	-	GMT	1960
+			 1:00	-	WAT
 
 # Nigeria
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Lagos	0:13:36 -	LMT	1919 Sep
-			1:00	-	CAT
+			1:00	-	WAT
 
 # Reunion
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Indian/Reunion	3:41:52 -	LMT	1911 Jun	# Saint-Denis
 			4:00	-	RET	# Reunion Time
+#
+# Scattered Islands (Iles Eparses) administered from Reunion are as follows.
+# The following information about them is taken from
+# Iles Eparses (www.outre-mer.gouv.fr/domtom/ile.htm, 1997-07-22, in French;
+# no longer available as of 1999-08-17).
+# We have no info about their time zone histories.
+#
+# Bassas da India - uninhabited
+# Europa Island - inhabited from 1905 to 1910 by two families
+# Glorioso Is - inhabited until at least 1958
+# Juan de Nova - uninhabited
+# Tromelin - inhabited until at least 1958
 
 # Rwanda
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Kigali	2:00:16 -	LMT	1935 Jun
-			2:00	-	SAT
+			2:00	-	CAT
 
 # St Helena
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Atlantic/St_Helena	-0:22:48 -	LMT	1890		# Jamestown
-			-0:06	-	SHT	1951	# St Helena Time (?)
+			-0:22:48 -	JMT	1951	# Jamestown Mean Time
 			 0:00	-	GMT
 # The other parts of the St Helena territory are similar:
-#	Tristan da Cunha: on GMT, says Whitman
-#	Ascension: on GMT, says usno1995
-#	Gough, Inaccessible, Nightingale: no information, but probably GMT
+#	Tristan da Cunha: on GMT, say Whitman and the CIA
+#	Ascension: on GMT, says usno1995 and the CIA
+#	Gough (scientific station since 1955; sealers wintered previously):
+#		on GMT, says the CIA
+#	Inaccessible, Nightingale: no information, but probably GMT
 
 # Sao Tome and Principe
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Sao_Tome	 0:26:56 -	LMT	1884
 			-0:36:32 -	LMT	1912	# Lisbon Mean Time
-			 0:00	-	WAT
+			 0:00	-	GMT
 
 # Senegal
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Dakar	-1:09:44 -	LMT	1912
-			-1:00	-	AAT	1941 Jun
-			 0:00	-	WAT
+			-1:00	-	WAT	1941 Jun
+			 0:00	-	GMT
 
 # Seychelles
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -550,42 +487,44 @@ Zone	Indian/Mahe	3:41:48 -	LMT	1906 Jun	# Victoria
 # Sierra Leone
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 # Whitman gives Mar 31 - Aug 31 for 1931 on; go with Shanks.
-Rule	SL	1935	1942	-	Jun	 1	0:00	1:00	S
-Rule	SL	1935	1942	-	Oct	 1	0:00	0	-
-Rule	SL	1957	1962	-	Jun	 1	0:00	1:00	S
-Rule	SL	1957	1962	-	Sep	 1	0:00	0	-
+Rule	SL	1935	1942	-	Jun	 1	0:00	0:40	SLST
+Rule	SL	1935	1942	-	Oct	 1	0:00	0	WAT
+Rule	SL	1957	1962	-	Jun	 1	0:00	1:00	SLST
+Rule	SL	1957	1962	-	Sep	 1	0:00	0	GMT
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Freetown	-0:53:00 -	LMT	1882
 			-0:53:00 -	FMT	1913 Jun # Freetown Mean Time
-			-1:00	SL	AA%sT	1957
-			 0:00	SL	WA%sT
+			-1:00	SL	%s	1957
+			 0:00	SL	%s
 
 # Somalia
-# From Paul Eggert <eggert@twinsun.com> (1993-11-18):
-# Shanks omits the 1948 transition to 2:45; this is probably a typo.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Mogadishu	3:01:28 -	LMT	1893 Nov
 			3:00	-	EAT	1931
-			2:30	-	BEAT	1948
-			2:45	-	BEAT	1957	# not in Shanks
+			2:30	-	BEAT	1957
 			3:00	-	EAT
 
 # South Africa
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	SA	1942	1943	-	Sep	Sun>=15	2:00	1:00	S
+Rule	SA	1942	1943	-	Sep	Sun>=15	2:00	1:00	-
 Rule	SA	1943	1944	-	Mar	Sun>=15	2:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Johannesburg 1:52:00 -	LMT	1892 Feb 8
-			1:30	-	SAT	1903 Mar
-			2:00	SA	SA%sT
-# Prince Edward Is
+			1:30	-	SAST	1903 Mar
+			2:00	SA	SAST
+# Marion and Prince Edward Is
+# scientific station since 1947
 # no information
 
 # Sudan
-# From Michael Ross <mross@antigone.com> (1995-11-15):
-# Sudan no longer observes any form of daylight time change.
-# I verified this today by telephone with the Sudan Mission to the
-# United Nations: 212-573-6033
+#
+# From <a href="http://www.sunanews.net/sn13jane.html">
+# Sudan News Agency (2000-01-13)
+# </a>, also reported by Michael De Beukelaer-Dossche via Steffen Thorsen:
+# Clocks will be moved ahead for 60 minutes all over the Sudan as of noon
+# Saturday....  This was announced Thursday by Caretaker State Minister for
+# Manpower Abdul-Rahman Nur-Eddin.
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Sudan	1970	only	-	May	 1	0:00	1:00	S
 Rule	Sudan	1970	1985	-	Oct	15	0:00	0	-
@@ -593,27 +532,25 @@ Rule	Sudan	1971	only	-	Apr	30	0:00	1:00	S
 Rule	Sudan	1972	1985	-	Apr	lastSun	0:00	1:00	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Khartoum	2:10:08 -	LMT	1931
-			2:00	Sudan	EE%sT
+			2:00	Sudan	CA%sT	2000 Jan 15 12:00
+			3:00	-	EAT
 
 # Swaziland
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Mbabane	2:04:24 -	LMT	1903 Mar
-			2:00	-	SAT
+			2:00	-	SAST
 
 # Tanzania
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Dar_es_Salaam 2:37:08 -	LMT	1931
 			3:00	-	EAT	1948
-			2:45	-	BEAT	1961
+			2:45	-	BEAUT	1961
 			3:00	-	EAT
 
 # Togo
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Lome	0:04:52 -	LMT	1893
-			0:00	-	WAT
-
-# Tromelin
-# uninhabited
+			0:00	-	GMT
 
 # Tunisia
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -650,22 +587,15 @@ Zone	Africa/Tunis	0:40:44 -	LMT	1881 May 12
 Zone	Africa/Kampala	2:09:40 -	LMT	1928 Jul
 			3:00	-	EAT	1930
 			2:30	-	BEAT	1948
-			2:45	-	BEAT	1957
+			2:45	-	BEAUT	1957
 			3:00	-	EAT
 
-# Zaire
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Africa/Kinshasa	1:01:12 -	LMT	1897 Nov 9
-			1:00	-	CAT
-Zone Africa/Lubumbashi	1:49:52 -	LMT	1897 Nov 9
-			2:00	-	SAT
-
 # Zambia
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Lusaka	1:53:08 -	LMT	1903 Mar
-			2:00	-	SAT
+			2:00	-	CAT
 
 # Zimbabwe
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Harare	2:04:12 -	LMT	1903 Mar
-			2:00	-	SAT
+			2:00	-	CAT
diff --git a/zic.tproj/datfiles/antarctica b/zic.tproj/datfiles/antarctica
index 01262d7..c98e528 100644
--- a/zic.tproj/datfiles/antarctica
+++ b/zic.tproj/datfiles/antarctica
@@ -1,13 +1,32 @@
-#	$OpenBSD: antarctica,v 1.3 1997/01/14 04:36:48 millert Exp $
-# @(#)antarctica	7.5
+# @(#)antarctica	7.21
 
-# From Paul Eggert (1996-09-03):
-# To keep things manageable, we list only locations occupied year-round;
-# see <URL:http://earth.agu.org/amen/nations.html> (1996-05-24).
+# From Paul Eggert (1999-11-15):
+# To keep things manageable, we list only locations occupied year-round; see
+# <a href="http://www.comnap.aq/comnap/comnap.nsf/P/Stations/">
+# COMNAP - Stations and Bases
+# </a>
+# and
+# <a href="http://www.spri.cam.ac.uk/bob/periant.htm">
+# Summary of the Peri-Antarctic Islands (1998-07-23)
+# </a>
+# for information.
 # Unless otherwise specified, we have no time zone information.
 #
+# Except for the French entries,
 # I made up all time zone abbreviations mentioned here; corrections welcome!
-# FORMAT is `___' and GMTOFF is 0 for locations while uninhabited.
+# FORMAT is `zzz' and GMTOFF is 0 for locations while uninhabited.
+
+# These rules are stolen from the `europe' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	RussAQ	1981	1984	-	Apr	 1	 0:00	1:00	S
+Rule	RussAQ	1981	1983	-	Oct	 1	 0:00	0	-
+Rule	RussAQ	1984	1991	-	Sep	lastSun	 2:00s	0	-
+Rule	RussAQ	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
+Rule	RussAQ	1992	only	-	Mar	lastSat	 23:00	1:00	S
+Rule	RussAQ	1992	only	-	Sep	lastSat	 23:00	0	-
+Rule	RussAQ	1993	max	-	Mar	lastSun	 2:00s	1:00	S
+Rule	RussAQ	1993	1995	-	Sep	lastSun	 2:00s	0	-
+Rule	RussAQ	1996	max	-	Oct	lastSun	 2:00s	0	-
 
 # These rules are stolen from the `southamerica' file.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -20,53 +39,108 @@ Rule	ArgAQ	1974	only	-	Jan	23	0:00	1:00	S
 Rule	ArgAQ	1974	only	-	May	 1	0:00	0	-
 Rule	ArgAQ	1974	1976	-	Oct	Sun<=7	0:00	1:00	S
 Rule	ArgAQ	1975	1977	-	Apr	Sun<=7	0:00	0	-
-Rule	ChileAQ	1969	max	-	Oct	Sun>=9	0:00	1:00	S
-Rule	ChileAQ	1970	max	-	Mar	Sun>=9	0:00	0	-
+Rule	ChileAQ	1969	1997	-	Oct	Sun>=9	0:00	1:00	S
+Rule	ChileAQ	1970	1998	-	Mar	Sun>=9	0:00	0	-
+Rule	ChileAQ	1998	only	-	Sep	27	0:00	1:00	S
+Rule	ChileAQ	1999	only	-	Apr	 4	0:00	0	-
+Rule	ChileAQ	1999	max	-	Oct	Sun>=9	0:00	1:00	S
+Rule	ChileAQ	2000	max	-	Mar	Sun>=9	0:00	0	-
 
 
-# Argentina - 6 year-round bases
-# General Belgrano II
-# 5 others
+# Argentina - year-round bases
+# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
+# Esperanza, San Martin Land, -6323-05659, since 1952-12-17
+# Jubany, Potter Peninsula, King George Island, -6414-0602320, since 1982-01
+# Marambio, Seymour I, -6414-05637, since 1969-10-29
+# Orcadas, Laurie I, -6016-04444, since 1904-02-22
+# San Martin, Debenham I, -6807-06708, since 1951-03-21
+#	(except 1960-03 / 1976-03-21)
 
 # Australia - territories
-# Heard Island, McDonald Islands
+# Heard Island, McDonald Islands (uninhabited)
+#	previously sealers and scientific personnel wintered
+#	<a href="http://www.dstc.qut.edu.au/DST/marg/daylight.html">
+#	Margaret Turner reports
+#	</a> (1999-09-30) that they're UTC+5, with no DST;
+#	presumably this is when they have visitors.
 #
 # year-round bases
-# Casey, Bailey Peninsula, since 1969
-# Davis, Vestfold Hills, since 1957-01-13 (except 1965-01 -  1969-02)
-# Mawson, Holme Bay, since 1954-02-13
+# Casey, Bailey Peninsula, -6617+11032, since 1969
+# Davis, Vestfold Hills, -6835+07759, since 1957-01-13
+#	(except 1964-11 - 1969-02)
+# Mawson, Holme Bay, -6736+06253, since 1954-02-13
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Casey	0	-	___	1969
+Zone Antarctica/Casey	0	-	zzz	1969
 			8:00	-	WST	# Western (Aus) Standard Time
-#Zone Antartica/Davis	unknown
-Zone Antarctica/Mawson	0	-	___	1954 Feb 13
+Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
+			7:00	-	DAVT	1964 Nov # Davis Time
+			0	-	zzz	1969 Feb
+			7:00	-	DAVT
+Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
 			6:00	-	MAWT	# Mawson Time
 # References:
-# <URL:http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html> (1996-07-15)
-# <URL:http://www.antdiv.gov.au/aad/exop/sfo/mawson/video.html> (1996-04-19)
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
+# Casey Weather (1998-02-26)
+# </a>
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/davis/video.html">
+# Davis Station, Antarctica (1998-02-26)
+# </a>
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/mawson/video.html">
+# Mawson Station, Antarctica (1998-02-25)
+# </a>
 
 # Brazil - year-round base
 # Ferraz, King George Island, since 1983/4
 
-# Chile - 4 year-round bases
+# Chile - year-round bases
+# Escudero, South Shetland Is, -621157-0585735, since 1994
+# Frei, King George Is, -6214-05848, since 1969
+# O'Higgins, Antarctic Peninsula, -6319-05704, since 1948-02
+# Prat, -6230-05941
 
 # China - year-round bases
 # Great Wall, King George Island, since 1985-02-20
 # Zhongshan, Larsemann Hills, Prydz Bay, since 1989-02-26
 
-# Finland - year-round base
-# Aboa, Queen Maud Land, since 1988
-
-# France
+# France - year-round bases
+#
+# From Antoine Leca <Antoine.Leca@Renault.FR> (1997-01-20):
+# Time data are from Nicole Pailleau at the IFRTP
+# (French Institute for Polar Research and Technology).
+# She confirms that French Southern Territories and Terre Adelie bases
+# don't observe daylight saving time, even if Terre Adelie supplies came
+# from Tasmania.
 #
 # French Southern Territories with year-round inhabitants
-# Amsterdam Island
-# Crozet Islands
-# Kerguelen Islands
-# St Paul Island
 #
-# year-round base
-# Dumont d'Urville, Adelie Land, since IGY
+# Martin-de-Vivies Base, Amsterdam Island, -374105+0773155, since 1950
+# Alfred-Faure Base, Crozet Islands, -462551+0515152, since 1964
+# Port-aux-Francais, Kerguelen Islands, -492110+0701303, since 1951;
+#	whaling & sealing station operated 1908/1914, 1920/1929, and 1951/1956
+#
+# St Paul Island - near Amsterdam, uninhabited
+#	fishing stations operated variously 1819/1931
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Kerguelen	0	-	zzz	1950	# Port-aux-Francais
+			5:00	-	TFT	# ISO code TF Time
+#
+# year-round base in the main continent
+# Dumont-d'Urville, Ile des Petrels, -6640+14001, since 1956-11
+#
+# Another base at Port-Martin, 50km east, began operation in 1947.
+# It was destroyed by fire on 1952-01-14.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/DumontDUrville 0 -	zzz	1947
+			10:00	-	PMT	1952 Jan 14 # Port-Martin Time
+			0	-	zzz	1956 Nov
+			10:00	-	DDUT	# Dumont-d'Urville Time
+# Reference:
+# <a href="http://www.icair.iac.org.nz/science/reports/fr/IFRTP.html">
+# Support and Development of Polar Research and Technology (1997-02-03)
+# </a>
+
 
 # Germany - year-round base
 # Georg von Neumayer
@@ -77,13 +151,29 @@ Zone Antarctica/Mawson	0	-	___	1954 Feb 13
 # Japan - year-round bases
 # Dome Fuji
 # Syowa
+#
+# From Hideyuki Suzuki (1999-02-06):
+# In all Japanese stations, +0300 is used as the standard time.  [See]
+# <a href="http://www.crl.go.jp/uk/uk201/basyo.htm">[reference in Japanese]</a>
+# and information from KAMO Hiroyasu <wd@ics.nara-wu.ac.jp>.
+#
+# Syowa station, which is the first antarctic station of Japan,
+# was established on 1957-01-29.  Since Syowa station is still the main
+# station of Japan, it's appropriate for the principal location.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Syowa	0	-	zzz	1957 Jan 29
+			3:00	-	SYOT	# Syowa Time
+# See:
+# <a href="http://www.nipr.ac.jp/english/ara01.html">
+# NIPR Antarctic Research Activities (1999-08-17)
+# </a>
 
 # S Korea - year-round base
 # King Sejong, King George Island, since 1988
 
 # New Zealand - claims
-# Balleny Islands
-# Scott Island
+# Balleny Islands (never inhabited)
+# Scott Island (never inhabited)
 #
 # year-round base
 # Scott, Ross Island, since 1957-01, is like Antarctica/McMurdo.
@@ -99,20 +189,38 @@ Rule	NZAQ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
 Rule	NZAQ	1990	max	-	Mar	Sun>=15	2:00s	0	S
 
 # Norway - territories
-# Bouvet (uninhabited)
+# Bouvet (never inhabited)
 #
 # claims
-# Peter I Island (uninhabited)
+# Peter I Island (never inhabited)
 
 # Poland - year-round base
-# Arctowski, King George Island, since 1977
+# Arctowski, King George Island, -620945-0582745, since 1977
 
 # Russia - year-round bases
-# Bellingshausen, King George Island
-# Mirny
-# Molodezhnaya
-# Novolazarevskaya
-# Vostok
+# Bellingshausen, King George Island, -621159-0585337, since 1968-02-22
+# Mirny, Davis coast, -6633+09301, since 1956-02
+# Molodezhnaya, Alasheyev Bay, year-round from 1962-02 to 1999-07-01
+# Novolazarevskaya, Queen Maud Land, -7046+01150,
+#	year-round from 1960/61 to 1992
+
+# Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11
+# <a href="http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP">
+# From Craig Mundell (1994-12-15)</a>:
+# Vostok, which is one of the Russian stations, is set on the same
+# time as Moscow, Russia.
+#
+# From Lee Hotz (2001-03-08):
+# I queried the folks at Columbia who spent the summer at Vostok and this is
+# what they had to say about time there:
+# ``in the US Camp (East Camp) we have been on New Zealand (McMurdo)
+# time, which is 12 hours ahead of GMT. The Russian Station Vostok was
+# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead
+# of GMT). This is a time zone I think two hours east of Moscow. The
+# natural time zone is in between the two: 8 hours ahead of GMT.''
+#
+Zone Antarctica/Vostok	0	-	zzz	1957 Dec 16
+			6:00	-	VOST	# Vostok time
 
 # S Africa - year-round bases
 # Marion Island
@@ -122,14 +230,23 @@ Rule	NZAQ	1990	max	-	Mar	Sun>=15	2:00s	0	S
 #
 # British Antarctic Territories (BAT) claims
 # South Orkney Islands
+#	scientific station from 1903
+#	whaling station at Signy I 1920/1926
 # South Shetland Islands
 #
 # year-round bases
-# Halley, Coates Land, -7535-2619, since 1956-01-06
+# Bird Island, South Georgia, -5400-03803, since 1983
+# Deception Island, -6259-06034, whaling station 1912/1931,
+#	scientific station 1943/1967,
+#	previously sealers and a scientific expedition wintered by accident,
+#	and a garrison was deployed briefly
+# Halley, Coates Land, -7535-02604, since 1956-01-06
+#	Halley is on a moving ice shelf and is periodically relocated
+#	so that it is never more than 10km from its nominal location.
 # Rothera, Adelaide Island, -6734-6808, since 1976-12-01
 
 # Uruguay - year round base
-# Artigas, King George Island
+# Artigas, King George Island, -621104-0585107
 
 # USA - year-round bases
 #
@@ -143,18 +260,19 @@ Rule	NZAQ	1990	max	-	Mar	Sun>=15	2:00s	0	S
 # Palmer used to be supplied from Argentina.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/Palmer	0	-	___	1965
+Zone Antarctica/Palmer	0	-	zzz	1965
 			-4:00	ArgAQ	AR%sT	1969 Oct 5
 			-3:00	ArgAQ	AR%sT	1982 May
 			-4:00	ChileAQ	CL%sT
 #
 #
-# McMurdo, Ross Island, since 1956
+# McMurdo, Ross Island, since 1955-12
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Antarctica/McMurdo	0	-	___	1956
+Zone Antarctica/McMurdo	0	-	zzz	1956
 			12:00	NZAQ	NZ%sT
 #
-# Amundsen-Scott, South Pole, since 1957-01-23
+# Amundsen-Scott, South Pole, continuously occupied since 1956-11-20
+#
 # From Paul Eggert (1996-09-03):
 # Normally it wouldn't have a separate entry, since it's like the
 # larger Antarctica/McMurdo since 1970, but it's too famous to omit.
@@ -167,8 +285,10 @@ Zone Antarctica/McMurdo	0	-	___	1956
 # which was on GMT+12 because New Zealand was on GMT+12 all year
 # at that time (1957).  (Source: Siple's book 90 degrees SOUTH.)
 #
-# From Susan Smith <URL:http://www.cybertours.com/whs/pole10.html>
-# (1995-11-13 16:24:56 +1300): We use the same time as McMurdo does.
+# From Susan Smith
+# http://www.cybertours.com/whs/pole10.html
+# (1995-11-13 16:24:56 +1300, no longer available):
+# We use the same time as McMurdo does.
 # And they use the same time as Christchurch, NZ does....
 # One last quirk about South Pole time.
 # All the electric clocks are usually wrong.
diff --git a/zic.tproj/datfiles/asia b/zic.tproj/datfiles/asia
index f921fb0..cfefc19 100644
--- a/zic.tproj/datfiles/asia
+++ b/zic.tproj/datfiles/asia
@@ -1,18 +1,18 @@
-#	$OpenBSD: asia,v 1.5 1997/01/14 04:36:48 millert Exp $
-# @(#)asia	7.27
+# @(#)asia	7.63
+
+# $FreeBSD: src/share/zoneinfo/asia,v 1.18 2001/04/06 16:46:52 wollman Exp $
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
 # tz@elsie.nci.nih.gov for general use in the future).
 
-# From Paul Eggert <eggert@twinsun.com> (1996-11-22):
+# From Paul Eggert <eggert@twinsun.com> (1999-03-22):
 #
 # A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
-# Except where otherwise noted, it is the source for the data below.
+# Thomas G. Shanks, The International Atlas (5th edition),
+# San Diego: ACS Publications, Inc. (1999).
 #
-# Gwillim Law <LAW@encmail.encompass.com> writes that a good source
+# Gwillim Law <Gwil_Law@bridge-point.com> writes that a good source
 # for recent time zone data is the International Air Transport
 # Association's Standard Schedules Information Manual (IATA SSIM),
 # published semiannually.  Law sent in several helpful summaries
@@ -26,8 +26,7 @@
 # I found in the UCLA library.
 #
 # A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and the discovery of the longitude,
-# Oxford University Press (1980).
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
 # I invented the abbreviations marked `*' in the following table;
 # the rest are from earlier versions of this file, or from other sources.
@@ -41,13 +40,12 @@
 #	5:30	IST	India
 #	7:00	ICT	Indochina*
 #	8:00	CST	China
+#	9:00	CJT	Central Japanese Time (1896/1937)*
 #	9:00	JST	Japan
 #	9:00	KST	Korea
 #	9:30	CST	(Australian) Central Standard Time
 #
 # See the `europe' file for Russia and Turkey in Asia.
-#
-# See the `africa' file for time zone naming and abbreviation conventions.
 
 # From Guy Harris:
 # Incorporates data for Singapore from Robert Elz' asia 1.1, as well as
@@ -81,24 +79,27 @@ Zone	Asia/Kabul	4:36:48 -	LMT	1890
 			4:30	-	AFT
 
 # Armenia
-# From Paul Eggert (1996-05-04):
+# From Paul Eggert (1999-10-29):
 # Shanks has Yerevan switching to 3:00 (with Russian DST) in spring 1991,
-# but usno1995 has Armenia at 4:00 (with DST), and Edgar Der-Danieliantz
-# <edd@AIC.NET> reported today that Yerevan probably won't use DST this year,
-# though it did use DST in 1995.  We guess Yerevan stayed in sync with Moscow
-# between 1990 and 1995, but stopped using DST in 1996.
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Armenia	1991	1995	-	Mar	lastSun	2:00s	1:00	S
-Rule	Armenia	1991	1995	-	Sep	lastSun	2:00s	0	-
+# then to 4:00 with no DST in fall 1995, then readopting Russian DST in 1997.
+# Go with Shanks, even when he disagrees with others.  Edgar Der-Danieliantz
+# <edd@AIC.NET> reported (1996-05-04) that Yerevan probably wouldn't use DST
+# in 1996, though it did use DST in 1995.  IATA SSIM (1991/1998) reports that
+# Armenia switched from 3:00 to 4:00 in 1998 and observed DST after 1991,
+# but started switching at 3:00s in 1998.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Yerevan	2:58:00 -	LMT	1924 May  2
 			3:00	-	YERT	1957 Mar    # Yerevan Time
 			4:00 RussiaAsia YER%sT	1991 Mar 31 2:00s
 			3:00	1:00	YERST	1991 Sep 23 # independence
-			3:00	Armenia	AM%sT	1992 Jan 19 2:00s # Armenia Time
-			4:00	Armenia	AM%sT
+			3:00 RussiaAsia	AM%sT	1995 Sep 24 2:00s
+			4:00	-	AMT	1997
+			4:00 RussiaAsia	AM%sT
 
 # Azerbaijan
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Azer	1997	max	-	Mar	lastSun	 1:00	1:00	S
+Rule	Azer	1997	max	-	Oct	lastSun	 1:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Baku	3:19:24 -	LMT	1924 May  2
 			3:00	-	BAKT	1957 Mar    # Baku Time
@@ -106,17 +107,18 @@ Zone	Asia/Baku	3:19:24 -	LMT	1924 May  2
 			3:00	1:00	BAKST	1991 Aug 30 # independence
 			3:00 RussiaAsia	AZ%sT	1992 Sep lastSun 2:00s
 			4:00	-	AZT	1996 # Azerbaijan time
-			4:00	EUAsia	AZ%sT
+			4:00	EUAsia	AZ%sT	1997
+			4:00	Azer	AZ%sT
 
 # Bahrain
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al-Manamah
+Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al Manamah
 			4:00	-	GST	1972 Jun
 			3:00	-	AST
 
 # Bangladesh
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Dacca	6:01:40 -	LMT	1890
+Zone	Asia/Dhaka	6:01:40 -	LMT	1890
 			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
 			6:30	-	BURT	1942 May 15 # Burma Time
 			5:30	-	IST	1942 Sep
@@ -126,7 +128,7 @@ Zone	Asia/Dacca	6:01:40 -	LMT	1890
 
 # Bhutan
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Thimbu	5:58:36 -	LMT	1947 Aug 15
+Zone	Asia/Thimphu	5:58:36 -	LMT	1947 Aug 15 # or Thimbu
 			5:30	-	IST	1987 Oct
 			6:00	-	BTT	# Bhutan Time
 
@@ -157,7 +159,7 @@ Zone	Asia/Phnom_Penh	6:59:40 -	LMT	1906 Jun  9
 			8:00	-	ICT	1931 May
 			7:00	-	ICT
 
-# People's Republic of China
+# China
 
 # From Guy Harris:
 # People's Republic of China.  Yes, they really have only one time zone.
@@ -186,7 +188,7 @@ Zone	Asia/Phnom_Penh	6:59:40 -	LMT	1906 Jun  9
 # note about Time magazine, though apparently _something_ happened in 1986.
 # Go with Shanks for now.  I made up names for the other pre-1980 time zones.
 
-# From Shanks (1991):
+# From Shanks:
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Shang	1940	only	-	Jun	 3	0:00	1:00	D
 Rule	Shang	1940	1941	-	Oct	 1	0:00	0	S
@@ -196,7 +198,7 @@ Rule	PRC	1986	only	-	May	 4	0:00	1:00	D
 Rule	PRC	1986	1991	-	Sep	Sun>=11	0:00	0	S
 Rule	PRC	1987	1991	-	Apr	Sun>=10	0:00	1:00	D
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Harbin	8:26:44	-	LMT	1928
+Zone	Asia/Harbin	8:26:44	-	LMT	1928 # or Haerbin
 			8:30	-	HART	1932 Mar # Harbin Time
 			8:00	-	CST	1940
 			9:00	-	HART	1966 May
@@ -205,20 +207,45 @@ Zone	Asia/Harbin	8:26:44	-	LMT	1928
 Zone	Asia/Shanghai	8:05:52	-	LMT	1928
 			8:00	Shang	C%sT	1949
 			8:00	PRC	C%sT
-Zone	Asia/Chungking	7:06:20	-	LMT	1928
+Zone	Asia/Chungking	7:06:20	-	LMT	1928 # or Chongqing
 			7:00	-	CHUT	1980 May # Chungking Time
 			8:00	PRC	C%sT
-Zone	Asia/Urumqi	5:50:20	-	LMT	1928
+Zone	Asia/Urumqi	5:50:20	-	LMT	1928 # or Urumchi
 			6:00	-	URUT	1980 May # Urumqi Time
 			8:00	PRC	C%sT
-Zone	Asia/Kashgar	5:03:56	-	LMT	1928
+Zone	Asia/Kashgar	5:03:56	-	LMT	1928 # or Kashi or Kaxgar
 			5:30	-	KAST	1940	 # Kashgar Time
 			5:00	-	KAST	1980 May
 			8:00	PRC	C%sT
+# Hong Kong (Xianggang)
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
+Rule	HK	1946	only	-	Dec	1	3:30	0	-
+Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
+Rule	HK	1947	only	-	Dec	30	3:30	0	-
+Rule	HK	1948	only	-	May	2	3:30	1:00	S
+Rule	HK	1948	1952	-	Oct	lastSun	3:30	0	-
+Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
+Rule	HK	1953	only	-	Nov	1	3:30	0	-
+Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
+Rule	HK	1954	only	-	Oct	31	3:30	0	-
+Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
+Rule	HK	1965	1977	-	Apr	Sun>=16	3:30	1:00	S
+Rule	HK	1965	1977	-	Oct	Sun>=16	3:30	0	-
+Rule	HK	1979	1980	-	May	Sun>=8	3:30	1:00	S
+Rule	HK	1979	1980	-	Oct	Sun>=16	3:30	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
+			8:00	HK	HK%sT
+
 
 ###############################################################################
 
-# Republic of China
+# Taiwan
+
+# Shanks writes that Taiwan observed DST during 1945, when it
+# was still controlled by Japan.  This is hard to believe, but we don't
+# have any other information.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Taiwan	1945	1951	-	May	1	0:00	1:00	D
@@ -236,30 +263,7 @@ Rule	Taiwan	1980	only	-	Sep	30	0:00	0	S
 Zone	Asia/Taipei	8:06:00 -	LMT	1896
 			8:00	Taiwan	C%sT
 
-###############################################################################
-# Hong Kong
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
-Rule	HK	1946	only	-	Dec	1	3:30	0	-
-Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
-Rule	HK	1947	only	-	Dec	30	3:30	0	-
-Rule	HK	1948	only	-	May	2	3:30	1:00	S
-Rule	HK	1948	1952	-	Oct	lastSun	3:30	0	-
-Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
-Rule	HK	1953	only	-	Nov	1	3:30	0	-
-Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
-Rule	HK	1954	only	-	Oct	31	3:30	0	-
-Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
-Rule	HK	1965	1977	-	Apr	Sun>=16	3:30	1:00	S
-Rule	HK	1965	1977	-	Oct	Sun>=16	3:30	0	-
-Rule	HK	1979	1980	-	May	Sun>=8	3:30	1:00	S
-Rule	HK	1979	1980	-	Oct	Sun>=16	3:30	0	-
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
-			8:00	HK	HK%sT	1997 Jul  1 # return to China
-			8:00	PRC	C%sT
-
-# Macao
+# Macao (Macau, Aomen)
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Macao	1961	1962	-	Mar	Sun>=16	3:30	1:00	S
 Rule	Macao	1961	1964	-	Nov	Sun>=1	3:30	0	-
@@ -292,11 +296,17 @@ Rule	Cyprus	1976	only	-	Oct	11	0:00	0	-
 Rule	Cyprus	1977	1980	-	Apr	Sun>=1	0:00	1:00	S
 Rule	Cyprus	1977	only	-	Sep	25	0:00	0	-
 Rule	Cyprus	1978	only	-	Oct	2	0:00	0	-
-Rule	Cyprus	1979	max	-	Sep	lastSun	0:00	0	-
-Rule	Cyprus	1981	max	-	Mar	lastSun	0:00	1:00	S
+Rule	Cyprus	1979	1997	-	Sep	lastSun	0:00	0	-
+Rule	Cyprus	1981	1998	-	Mar	lastSun	0:00	1:00	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Nicosia	2:13:28 -	LMT	1921 Nov 14
-			2:00	Cyprus	EE%sT
+			2:00	Cyprus	EE%sT	1998 Sep
+			2:00	EUAsia	EE%sT
+# IATA SSIM (1998-09) has Cyprus using EU rules for the first time.
+
+# Classically, Cyprus belongs to Asia; e.g. see Herodotus, Histories, I.72.
+# However, for various reasons many users expect to find it under Europe.
+Link	Asia/Nicosia	Europe/Nicosia
 
 # Georgia
 # From Paul Eggert <eggert@twinsun.com> (1994-11-19):
@@ -318,7 +328,39 @@ Zone	Asia/Tbilisi	2:59:16 -	LMT	1880
 			3:00 RussiaAsia GE%sT	1992 # Georgia Time
 			3:00 E-EurAsia	GE%sT	1994 Sep lastSun
 			4:00 E-EurAsia	GE%sT	1996 Oct lastSun
-			5:00	-	GET
+			4:00	1:00	GEST	1997 Mar lastSun
+			4:00 E-EurAsia	GE%sT
+
+# East Timor
+
+# From Joao Carrascalao, brother of the former governor of East Timor, in
+# <a href="http://etan.org/et99c/december/26-31/30ETMAY.htm">
+# East Timor may be late for its millennium
+# </a> (1999-12-26/31):
+# Portugal tried to change the time forward in 1974 because the sun
+# rises too early but the suggestion raised a lot of problems with the
+# Timorese and I still don't think it would work today because it
+# conflicts with their way of life.
+
+# From Paul Eggert (2000-12-04):
+# We don't have any record of the above attempt.
+# Most likely our records are incomplete, but we have no better data.
+
+# <a href="http://www.hri.org/news/world/undh/last/00-08-16.undh.html">
+# From Manoel de Almeida e Silva, Deputy Spokesman for the UN Secretary-General
+# (2000-08-16)</a>:
+# The Cabinet of the East Timor Transition Administration decided
+# today to advance East Timor's time by one hour.  The time change,
+# which will be permanent, with no seasonal adjustment, will happen at
+# midnight on Saturday, September 16.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Dili	8:22:20 -	LMT	1912
+			8:00	-	TPT	1942 Feb 21 23:00 # E Timor Time
+			9:00	-	JST	1945 Aug
+			9:00	-	TPT	1976 May  3
+			8:00	-	TPT	2000 Sep 17 00:00
+			9:00	-	TPT
 
 # India
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -336,7 +378,9 @@ Zone	Asia/Calcutta	5:53:28 -	LMT	1880
 # Indonesia
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Asia/Jakarta	7:07:12 -	LMT	1867 Aug 10
-			7:07:12	-	JMT	1924 Jan  1 0:13 # Jakarta MT
+# Shanks says the next transition was at 1924 Jan 1 0:13,
+# but this must be a typo.
+			7:07:12	-	JMT	1923 Dec 31 23:47:12 # Jakarta
 			7:20	-	JAVT	1932 Nov	 # Java Time
 			7:30	-	JAVT	1942 Mar 23
 			9:00	-	JST	1945 Aug
@@ -355,9 +399,12 @@ Zone Asia/Jayapura	9:22:48 -	LMT	1932 Nov
 			9:00	-	JAYT
 
 # Iran
-# From Paul Eggert (1996-12-17), following up a suggestion by Rich Wales:
-# Ahmad Alavi <URL:http://tehran.stanford.edu/Iran_Lib/Calendar/taghveem.txt>
-# (1993-08-04) writes ``Daylight saving time in Iran starts from the first day
+# From Paul Eggert (2000-06-12), following up a suggestion by Rich Wales:
+# Ahmea Alavi in
+# <a href="http://www.persia.org/Iran_Lib/Calendar/taghveem.txt">
+# TAGHVEEM (1993-07-12)
+# </a>
+# writes ``Daylight saving time in Iran starts from the first day
 # of Farvardin and ends the first day of Mehr.''  This disagrees with the SSIM:
 #
 #		   DST start	   DST end
@@ -367,8 +414,13 @@ Zone Asia/Jayapura	9:22:48 -	LMT	1932 Nov
 #	1993	03-21	03-21	09-23	09-23
 #	1994	03-21	03-21	09-22!= 09-23
 #	1995	03-21	03-21	09-22!= 09-23
-#	1996	03-21!=	03-20	09-21!= 09-22
-#	1997	03-21	03-21	09-21!= 09-23
+#	1996	03-21!=	03-20	09-22   09-22
+#	1997	03-22!=	03-21	09-22!= 09-23
+#	1998	03-21	03-21	09-21!= 09-23
+#	1999	03-22!=	03-21	09-22!= 09-23
+#	2000	03-21!=	03-20	09-21!= 09-22
+#	2001	03-19!=	03-21	09-19!= 09-23
+#	2002	03-18!=	03-21	09-18!= 09-23
 #
 # Go with Alavi starting with 1992.
 # I used Ed Reingold's cal-persia in GNU Emacs 19.34 to compute Persian dates.
@@ -433,7 +485,23 @@ Zone	Asia/Tehran	3:25:44	-	LMT	1916
 			4:00	Iran	IR%sT	1979
 			3:30	Iran	IR%sT
 
+
 # Iraq
+#
+# From Jonathan Lennox <lennox@cs.columbia.edu> (2000-06-12):
+# An article in this week's Economist ("Inside the Saddam-free zone", p. 50 in
+# the U.S. edition) on the Iraqi Kurds contains a paragraph:
+# "The three northern provinces ... switched their clocks this spring and
+# are an hour ahead of Baghdad."
+#
+# But Rives McDow (2000-06-18) quotes a contact in Iraqi-Kurdistan as follows:
+# In the past, some Kurdish nationalists, as a protest to the Iraqi
+# Government, did not adhere to daylight saving time.  They referred
+# to daylight saving as Saddam time.  But, as of today, the time zone
+# in Iraqi-Kurdistan is on standard time with Baghdad, Iraq.
+#
+# So we'll ignore the Economist's claim.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Iraq	1982	only	-	May	1	0:00	1:00	D
 Rule	Iraq	1982	1984	-	Oct	1	0:00	0	S
@@ -442,8 +510,9 @@ Rule	Iraq	1984	1985	-	Apr	1	0:00	1:00	D
 Rule	Iraq	1985	1990	-	Sep	lastSun	1:00s	0	S
 Rule	Iraq	1986	1990	-	Mar	lastSun	1:00s	1:00	D
 # IATA SSIM (1991/1996) says Apr 1 12:01am UTC; guess the `:01' is a typo.
+# Shanks says Iraq did not observe DST 1992/1997 or 1999 on; ignore this.
 Rule	Iraq	1991	max	-	Apr	 1	3:00s	1:00	D
-Rule	Iraq	1991	max	-	Oct	 1	3:00s	0	D
+Rule	Iraq	1991	max	-	Oct	 1	3:00s	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Baghdad	2:57:40	-	LMT	1890
 			2:57:36	-	BMT	1918	    # Baghdad Mean Time?
@@ -455,16 +524,27 @@ Zone	Asia/Baghdad	2:57:40	-	LMT	1890
 
 # Israel
 
-# From U. S. Naval Observatory (1989-01-19):
-# ISRAEL              2 H  AHEAD OF UTC
-# ISRAEL              3 H  AHEAD OF UTC  APR 10 - SEP 3
-
-# From Paul Eggert <eggert@twinsun.com> (1993-11-18):
+# From Ephraim Silverberg (2001-01-11):
+#
+# I coined "IST/IDT" circa 1988.  Until then there were three
+# different abbreviations in use:
+#
+# JST  Jerusalem Standard Time [Danny Braniss, Hebrew University]
+# IZT  Israel Zonal (sic) Time [Prof. Haim Papo, Technion]
+# EEST Eastern Europe Standard Time [used by almost everyone else]
+#
+# Since timezones should be called by country and not capital cities,
+# I ruled out JST.  As Israel is in Asia Minor and not Eastern Europe,
+# EEST was equally unacceptable.  Since "zonal" was not compatible with
+# any other timezone abbreviation, I felt that 'IST' was the way to go
+# and, indeed, it has received almost universal acceptance in timezone
+# settings in Israeli computers.
 #
-# Shanks gives the following rules for Jerusalem from 1918 through 1991.
-# After 1989 Shanks often disagrees with Silverberg; we go with Silverberg.
+# In any case, I am happy to share timezone abbreviations with India,
+# high on my favorite-country list (and not only because my wife's
+# family is from India).
 
-# From Shanks (1991):
+# From Shanks:
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Zion	1940	only	-	Jun	 1	0:00	1:00	D
 Rule	Zion	1942	1944	-	Nov	 1	0:00	0	S
@@ -507,22 +587,31 @@ Rule	Zion	1987	only	-	Sep	13	0:00	0	S
 Rule	Zion	1988	only	-	Apr	 9	0:00	1:00	D
 Rule	Zion	1988	only	-	Sep	 3	0:00	0	S
 
-# From Ephraim Silverberg (1996-01-02):
-#
+# From Ephraim Silverberg <ephraim@cs.huji.ac.il>
+# (1997-03-04, 1998-03-16, 1998-12-28, 2000-01-17 and 2000-07-25):
+
 # According to the Office of the Secretary General of the Ministry of
 # Interior, there is NO set rule for Daylight-Savings/Standard time changes.
-# Each year they decide anew what havoc to wreak on the country.  However,
-# there is a "supposed" set of rules which is subject to change depending
-# on the party the Minister of Interior, the size of the coalition
-# government, the phase of the moon and the direction of the wind.  Hence,
-# changes may need to be made on a semi-annual basis.  One thing is entrenched
-# in law, however: that there must be at least 150 days of daylight savings
-# time annually.  Ever since 1993, the change to daylight savings time has
-# been from midnight Thursday night to 1 a.m. Friday morning and the change
-# back to standard time on Saturday night from midnight daylight savings time
-# to 11 p.m. standard time.  1996 is an exception to this rule where the
-# change back to standard time takes place on Sunday night instead of Saturday
-# night to avoid conflicts with the Jewish New Year.
+# One thing is entrenched in law, however: that there must be at least 150
+# days of daylight savings time annually.  From 1993-1998, the change to
+# daylight savings time was on a Friday morning from midnight IST to
+# 1 a.m IDT; up until 1998, the change back to standard time was on a
+# Saturday night from midnight daylight savings time to 11 p.m. standard
+# time.  1996 is an exception to this rule where the change back to standard
+# time took place on Sunday night instead of Saturday night to avoid
+# conflicts with the Jewish New Year.  In 1999, the change to
+# daylight savings time was still on a Friday morning but from
+# 2 a.m. IST to 3 a.m. IDT; furthermore, the change back to standard time
+# was also on a Friday morning from 2 a.m. IDT to 1 a.m. IST for
+# 1999 only.  In the year 2000, the change to daylight savings time was
+# similar to 1999, but although the change back will be on a Friday, it
+# will take place from 1 a.m. IDT to midnight IST.  Starting in 2001, all
+# changes to/from will take place at 1 a.m. old time, but now there is no
+# rule as to what day of the week it will take place in as the start date
+# (except in 2003) is the night after the Passover Seder (i.e. the eve
+# of the 16th of Nisan in the lunar Hebrew calendar) and the end date
+# (except in 2002) is three nights before Yom Kippur [Day of Atonement]
+# (the eve of the 7th of Tishrei in the lunar Hebrew calendar).
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Zion	1989	only	-	Apr	30	0:00	1:00	D
@@ -538,34 +627,69 @@ Rule	Zion	1993	only	-	Sep	 5	0:00	0	S
 
 # The dates for 1994-1995 were obtained from Office of the Spokeswoman for the
 # Ministry of Interior, Jerusalem, Israel.  The spokeswoman can be reached by
-# calling the switchboard at 972-2-701411 and asking for the spokeswoman.
+# calling the office directly at 972-2-6701447 or 972-2-6701448.
 
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Rule	NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
 Rule	Zion	1994	only	-	Apr	 1	0:00	1:00	D
 Rule	Zion	1994	only	-	Aug	28	0:00	0	S
 Rule	Zion	1995	only	-	Mar	31	0:00	1:00	D
 Rule	Zion	1995	only	-	Sep	 3	0:00	0	S
 
-# The dates for 1996-1998 were also obtained from Office of the Spokeswoman
-# for the Ministry of Interior, Jerusalem, Israel.  The official announcement
-# can be viewed (in Hebrew) at the following URL:
+# The dates for 1996 were determined by the Minister of Interior of the
+# time, Haim Ramon.  The official announcement regarding 1996-1998
+# (with the dates for 1997-1998 no longer being relevant) can be viewed at:
+#
+#   ftp://ftp.huji.ac.il/pub/tz/announcements/1996-1998.ramon.ps.gz
+#
+# The dates for 1997-1998 were altered by his successor, Rabbi Eli Suissa.
+#
+# The official announcements for the years 1997-1999 can be viewed at:
 #
-#   ftp://ftp.huji.ac.il/pub/misc/timezones/announcements/1996-1998.ps.gz
+#   ftp://ftp.huji.ac.il/pub/tz/announcements/YYYY.ps.gz
 #
-# Caveat emptor: The dates for the years 1996-1998 were originally announced
-# on 1995-08-31, by the previous Minister of Interior.  The new Minister
-# of Interior changed the dates on 1996-01-01, to take into account the
-# desires of certain portions of Israeli society (the next election is in the
-# Fall of 1996).  After this (1996) year's Daylight Savings Time is over, the
-# new minister has announced that a study will be conducted as to the wishes of
-# the populace regarding the length of Daylight Savings Time and the Interior
-# Committee will meet to review the results of the study and make any necessary
-# changes to the 1997-1998 dates.  Never a dull moment in the State of Israel.
+#       where YYYY is the relevant year.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Zion	1996	1998	-	Mar	Fri>=14	0:00	1:00	D
+Rule	Zion	1996	only	-	Mar	15	0:00	1:00	D
 Rule	Zion	1996	only	-	Sep	16	0:00	0	S
-Rule	Zion	1997	1998	-	Oct	Sun>=14	0:00	0	S
+Rule	Zion	1997	only	-	Mar	21	0:00	1:00	D
+Rule	Zion	1997	only	-	Sep	14	0:00	0	S
+Rule	Zion	1998	only	-	Mar	20	0:00	1:00	D
+Rule	Zion	1998	only	-	Sep	 6	0:00	0	S
+Rule	Zion	1999	only	-	Apr	 2	2:00	1:00	D
+Rule	Zion	1999	only	-	Sep	 3	2:00	0	S
+
+# The Knesset Interior Committee has changed the dates for 2000 for
+# the third time in just over a year and have set new dates for the
+# years 2001-2004 as well.
+#
+# The official announcement for the start date of 2000 can be viewed at:
+#
+#	ftp://ftp.huji.ac.il/pub/tz/announcements/2000-start.ps.gz
+#
+# The official announcement for the end date of 2000 and the dates
+# for the years 2001-2004 can be viewed at:
+#
+#	ftp://ftp.huji.ac.il/pub/tz/announcements/2000-2004.ps.gz
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	2000	only	-	Apr	14	2:00	1:00	D
+Rule	Zion	2000	only	-	Oct	 6	1:00	0	S
+Rule	Zion	2001	only	-	Apr	 9	1:00	1:00	D
+Rule	Zion	2001	only	-	Sep	24	1:00	0	S
+Rule	Zion	2002	only	-	Mar	29	1:00	1:00	D
+Rule	Zion	2002	only	-	Oct	 7	1:00	0	S
+Rule	Zion	2003	only	-	Mar	28	1:00	1:00	D
+Rule	Zion	2003	only	-	Oct	 3	1:00	0	S
+Rule	Zion	2004	only	-	Apr	 7	1:00	1:00	D
+Rule	Zion	2004	only	-	Sep	22	1:00	0	S
+
+# From Paul Eggert (2000-07-25):
+# Here are guesses for rules after 2004.
+# They are probably wrong, but they are more likely than no DST at all.
+# Rule	NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
+Rule	Zion	2005	max	-	Apr	 1	1:00	1:00	D
+Rule	Zion	2005	max	-	Oct	 1	1:00	0	S
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Jerusalem	2:20:56 -	LMT	1880
@@ -592,36 +716,76 @@ Zone	Asia/Jerusalem	2:20:56 -	LMT	1880
 # but the only locations using it were US military bases.
 # We go with Shanks and omit daylight saving in those years for Asia/Tokyo.
 
+# From Hideyuki Suzuki (1998-11-09):
+# 'Tokyo' usually stands for the former location of Tokyo Astronomical
+# Observatory: E 139 44' 40".90 (9h 18m 58s.727), N 35 39' 16".0.
+# This data is from 'Rika Nenpyou (Chronological Scientific Tables) 1996'
+# edited by National Astronomical Observatory of Japan....
+# JST (Japan Standard Time) has been used since 1888-01-01 00:00 (JST).
+# The law is enacted on 1886-07-07.
+
+# From Hideyuki Suzuki (1998-11-16):
+# The ordinance No. 51 (1886) established "standard time" in Japan,
+# which stands for the time on E 135 degree.
+# In the ordinance No. 167 (1895), "standard time" was renamed to "central
+# standard time".  And the same ordinance also established "western standard
+# time", which stands for the time on E 120 degree....  But "western standard
+# time" was abolished in the ordinance No. 529 (1937).  In the ordinance No.
+# 167, there is no mention regarding for what place western standard time is
+# standard....
+#
+# I wrote "ordinance" above, but I don't know how to translate.
+# In Japanese it's "chokurei", which means ordinance from emperor.
+
+# Shanks claims JST in use since 1896, and that a few places (e.g. Ishigaki)
+# use +0800; go with Suzuki.  Guess that all ordinances took effect on Jan 1.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Tokyo	9:19:04	-	LMT	1896
+Zone	Asia/Tokyo	9:18:59	-	LMT	1887 Dec 31 15:00u
+			9:00	-	JST	1896
+			9:00	-	CJT	1938
 			9:00	-	JST
-Zone	Asia/Ishigaki	8:16:36	-	LMT	1896
-			8:00	-	CST
-# There is no information for Marcus.
-# Other Japanese possessions are probably like Asia/Tokyo.
+# Since 1938, all Japanese possessions have been like Asia/Tokyo.
 
 # Jordan
+#
+# From <a href="http://star.arabia.com/990701/JO9.html">
+# Jordan Week (1999-07-01) </a> via Steffen Thorsen (1999-09-09):
+# Clocks in Jordan were forwarded one hour on Wednesday at midnight,
+# in accordance with the government's decision to implement summer time
+# all year round.
+#
+# From <a href="http://star.arabia.com/990930/JO9.html">
+# Jordan Week (1999-09-30) </a> via Steffen Thorsen (1999-11-09):
+# Winter time starts today Thursday, 30 September. Clocks will be turned back
+# by one hour.  This is the latest government decision and it's final!
+# The decision was taken because of the increase in working hours in
+# government's departments from six to seven hours.
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule    Jordan	1973	only	-	Jun	6	0:00	1:00	S
-Rule    Jordan	1973	1975	-	Oct	1	0:00	0	-
-Rule    Jordan	1974	1977	-	May	1	0:00	1:00	S
-Rule    Jordan	1976	only	-	Nov	1	0:00	0	-
-Rule    Jordan	1977	only	-	Oct	1	0:00	0	-
-Rule    Jordan	1978	only	-	Apr	30	0:00	1:00	S
-Rule    Jordan	1978	only	-	Sep	30	0:00	0	-
-Rule    Jordan	1985	only	-	Apr	1	0:00	1:00	S
-Rule    Jordan	1985	only	-	Oct	1	0:00	0	-
-Rule    Jordan	1986	1988	-	Apr	Fri>=1	0:00	1:00	S
-Rule    Jordan	1986	1990	-	Oct	Fri>=1	0:00	0	-
-Rule    Jordan	1989	only	-	May	8	0:00	1:00	S
-Rule    Jordan	1990	only	-	Apr	27	0:00	1:00	S
-Rule    Jordan	1991	only	-	Apr	17	0:00	1:00	S
-Rule    Jordan	1991	only	-	Sep	27	0:00	0	-
-Rule    Jordan	1992	only	-	Apr	10	0:00	1:00	S
-Rule    Jordan	1992	1993	-	Oct	Fri>=1	0:00	0	-
-Rule    Jordan	1993	max	-	Apr	Fri>=1	0:00	1:00	S
-Rule    Jordan	1994	only	-	Sep	Fri>=15	0:00	0	-
-Rule    Jordan	1995	max	-	Sep	Fri>=15	0:00s	0	-
+Rule	Jordan	1973	only	-	Jun	6	0:00	1:00	S
+Rule	Jordan	1973	1975	-	Oct	1	0:00	0	-
+Rule	Jordan	1974	1977	-	May	1	0:00	1:00	S
+Rule	Jordan	1976	only	-	Nov	1	0:00	0	-
+Rule	Jordan	1977	only	-	Oct	1	0:00	0	-
+Rule	Jordan	1978	only	-	Apr	30	0:00	1:00	S
+Rule	Jordan	1978	only	-	Sep	30	0:00	0	-
+Rule	Jordan	1985	only	-	Apr	1	0:00	1:00	S
+Rule	Jordan	1985	only	-	Oct	1	0:00	0	-
+Rule	Jordan	1986	1988	-	Apr	Fri>=1	0:00	1:00	S
+Rule	Jordan	1986	1990	-	Oct	Fri>=1	0:00	0	-
+Rule	Jordan	1989	only	-	May	8	0:00	1:00	S
+Rule	Jordan	1990	only	-	Apr	27	0:00	1:00	S
+Rule	Jordan	1991	only	-	Apr	17	0:00	1:00	S
+Rule	Jordan	1991	only	-	Sep	27	0:00	0	-
+Rule	Jordan	1992	only	-	Apr	10	0:00	1:00	S
+Rule	Jordan	1992	1993	-	Oct	Fri>=1	0:00	0	-
+Rule	Jordan	1993	1998	-	Apr	Fri>=1	0:00	1:00	S
+Rule	Jordan	1994	only	-	Sep	Fri>=15	0:00	0	-
+Rule	Jordan	1995	1998	-	Sep	Fri>=15	0:00s	0	-
+Rule	Jordan	1999	only	-	Jul	 1	0:00s	1:00	S
+Rule	Jordan	1999	max	-	Sep	lastThu	0:00s	0	-
+Rule	Jordan	2000	max	-	Mar	lastThu	0:00s	1:00	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Amman	2:23:44 -	LMT	1931
 			2:00	Jordan	EE%sT
@@ -635,7 +799,7 @@ Zone	Asia/Amman	2:23:44 -	LMT	1931
 # IATA SSIM mentions a third time zone in Kazakhstan.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Alma-Ata	5:07:48 -	LMT	1924 May  2 # or Almaty
+Zone	Asia/Almaty	5:07:48 -	LMT	1924 May  2 # or Alma-Ata
 			5:00	-	ALMT	1957 Mar # Alma-Ata Time
 			6:00 RussiaAsia ALM%sT	1991 Mar 31 2:00s
 			5:00	1:00	ALMST	1991 Sep 29 2:00s
@@ -655,27 +819,30 @@ Zone	Asia/Aqtau	3:21:04	-	LMT	1924 May  2 # or Aktau
 			5:00 E-EurAsia	AQT%sT	1995 Sep lastSun
 			4:00 E-EurAsia	AQT%sT
 
-# Kirgizstan
+# Kyrgyzstan (Kirgizstan)
+# Transitions through 1991 are from Shanks.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Kirgiz	1992	max	-	Apr	Sun>=7	0:00	1:00	S
-Rule	Kirgiz	1991	max	-	Sep	lastSun	0:00	0	-
+Rule	Kirgiz	1992	1996	-	Apr	Sun>=7	0:00	1:00	S
+Rule	Kirgiz	1992	1996	-	Sep	lastSun	0:00	0	-
+Rule	Kirgiz	1997	max	-	Mar	lastSun	2:30	1:00	S
+Rule	Kirgiz	1997	max	-	Oct	lastSun	2:30	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Bishkek	4:58:24 -	LMT	1924 May  2
-			5:00	-	FRUT	1957 Mar    # Frunze Time
+			5:00	-	FRUT	1930 Jun 21 # Frunze Time
 			6:00 RussiaAsia FRU%sT	1991 Mar 31 2:00s
-			5:00	1:00	FRUST	1991 Aug 31 # independence
+			5:00	1:00	FRUST	1991 Aug 31 2:00 # independence
 			5:00	Kirgiz	KG%sT		    # Kirgizstan Time
 
 ###############################################################################
 
-# Korea
+# Korea (North and South)
 
 # From Guy Harris:
 # According to someone at the Korean Times in San Francisco,
 # Daylight Savings Time was not observed until 1987.  He did not know
 # at what time of day DST starts or ends.
 
-# From Shanks (1991):
+# From Shanks:
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	ROK	1960	only	-	May	15	0:00	1:00	D
 Rule	ROK	1960	only	-	Sep	13	0:00	0	S
@@ -708,7 +875,7 @@ Zone	Asia/Kuwait	3:11:56 -	LMT	1950
 
 # Laos
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Vientiane	6:50:24 -	LMT	1906 Jun  9
+Zone	Asia/Vientiane	6:50:24 -	LMT	1906 Jun  9 # or Viangchan
 			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
 			7:00	-	ICT	1912 May
 			8:00	-	ICT	1931 May
@@ -738,7 +905,8 @@ Rule	Lebanon	1989	only	-	May	10	0:00	1:00	S
 Rule	Lebanon	1990	1992	-	May	1	0:00	1:00	S
 Rule	Lebanon	1992	only	-	Oct	4	0:00	0	-
 Rule	Lebanon	1993	max	-	Mar	lastSun	0:00	1:00	S
-Rule	Lebanon	1993	max	-	Sep	lastSun	0:00	0	-
+Rule	Lebanon	1993	1998	-	Sep	lastSun	0:00	0	-
+Rule	Lebanon	1999	max	-	Oct	lastSun	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Beirut	2:22:00 -	LMT	1880
 			2:00	Lebanon	EE%sT
@@ -770,29 +938,62 @@ Zone	Indian/Maldives	4:54:00 -	LMT	1880	# Male
 			5:00	-	MVT		# Maldives Time
 
 # Mongolia
-# Shanks says that Mongolia has three time zones, but usno1995 and
-# <URL:http://www.odci.gov/cia/publications/95fact/802389h.gif> (1995)
+
+# Shanks says that Mongolia has three time zones, but usno1995 and the CIA map
+# Standard Time Zones of the World (1997-01)
 # both say that it has just one.
-# Let's comment out the western and eastern Mongolian time zones
-# till we know what their principal towns are.
+
+# From Oscar van Vlijmen (1999-12-11):
+# <a href="http://www.mongoliatourism.gov.mn/general.htm">
+# General Information Mongolia
+# </a> (1999-09)
+# "Time: Mongolia has two time zones. Three westernmost provinces of
+# Bayan-Ulgii, Uvs, and Hovd are one hour earlier than the capital city, and
+# the rest of the country follows the Ulaanbaatar time, which is UTC/GMT plus
+# eight hours."
+
+# From Rives McDow (1999-12-13):
+# Mongolia discontinued the use of daylight savings time in 1999; 1998
+# being the last year it was implemented.  The dates of implementation I am
+# unsure of, but most probably it was similar to Russia, except for the time
+# of implementation may have been different....
+# Some maps in the past have indicated that there was an additional time
+# zone in the eastern part of Mongolia, including the provinces of Dornod,
+# Suhbaatar, and possibly Khentij.
+
+# From Paul Eggert (1999-12-15):
+# For now, we'll comment out the east zone (Choybalsan)
+# and use Shanks's and the IATA's data for the daylight-saving rules.
+# Naming and spelling is tricky in Mongolia.
+# We'll use Hovd (also spelled Chovd and Khovd) to represent the west zone;
+# the capital of the Hovd province is sometimes called Hovd, sometimes Dund-Us,
+# and sometimes Jirgalanta (with variant spellings), but the name Hovd
+# is good enough for our purposes.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Mongol	1981	1984	-	Apr	1	0:00	1:00	S
 Rule	Mongol	1981	1984	-	Oct	1	0:00	0	-
 Rule	Mongol	1985	1990	-	Mar	lastSun	2:00	1:00	S
 Rule	Mongol	1985	1990	-	Sep	lastSun	3:00	0	-
-Rule	Mongol	1991	max	-	Mar	lastSun	0:00	1:00	S
+Rule	Mongol	1991	1998	-	Mar	lastSun	0:00	1:00	S
 Rule	Mongol	1991	1995	-	Sep	lastSun	0:00	0	-
-Rule	Mongol	1996	max	-	Oct	Fri>=22	0:00	0	-
+# IATA SSIM (1996-09) says 1996-10-25; go with Shanks.
+Rule	Mongol	1996	only	-	Oct	lastSun	0:00	0	-
+Rule	Mongol	1997	1998	-	Sep	lastSun	0:00	0	-
+# IATA SSIM (1999-09) says Mongolia no longer observes DST.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-#Zone	Asia/Dariv	6:14:32 -	LMT	1905 Aug
-#			6:00	-	DART	1978	# Dariv Time
-#			7:00	Mongol	DAR%sT
-Zone	Asia/Ulan_Bator	7:07:32 -	LMT	1905 Aug
-			7:00	-	ULAT	1978	# Ulan Bator Time
+Zone	Asia/Hovd	6:06:36 -	LMT	1905 Aug
+			6:00	-	HOVT	1978	# Hovd Time
+			7:00	Mongol	HOV%sT
+Zone	Asia/Ulaanbaatar 7:07:32 -	LMT	1905 Aug
+			7:00	-	ULAT	1978	# Ulaanbaatar Time
 			8:00	Mongol	ULA%sT
-#Zone Asia/Baruun-Urt	7:33:00 -	LMT	1905 Aug
-#			8:00	-	BART	1978	# Baruun-Urt Time
-#			9:00	Mongol	BAR%sT
+# We're not sure about this entry yet, so we'll omit it for now.
+#Zone Asia/Choybalsan	7:38:00 -	LMT	1905 Aug
+#			8:00	-	CHOT	1978	# Choybalsan Time
+#			9:00	Mongol	CHO%sT	19??
+#			8:00	Mongol	ULA%sT
 
 # Nepal
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -815,7 +1016,80 @@ Zone	Asia/Karachi	4:28:12 -	LMT	1907
 			5:00	-	PKT	# Pakistan Time
 
 # Palestine
-# These rules for Egypt are stolen from the `africa' file.
+
+# From Amos Shapir <amos@nsof.co.il> (1998-02-15):
+#
+# From 1917 until 1948-05-15, all of Palestine, including the parts now
+# known as the Gaza Strip and the West Bank, was under British rule.
+# Therefore the rules given for Israel for that period, apply there too...
+#
+# The Gaza Strip was under Egyptian rule between 1948-05-15 until 1967-06-05
+# (except a short occupation by Israel from 1956-11 till 1957-03, but no
+# time zone was affected then).  It was never formally annexed to Egypt,
+# though.
+#
+# The rest of Palestine was under Jordanian rule at that time, formally
+# annexed in 1950 as the West Bank (and the word "Trans" was dropped from
+# the country's previous name of "the Hashemite Kingdom of the
+# Trans-Jordan").  So the rules for Jordan for that time apply.  Major
+# towns in that area are Nablus (Shchem), El-Halil (Hebron), Ramallah, and
+# East Jerusalem.
+#
+# Both areas were occupied by Israel in June 1967, but not annexed (except
+# for East Jerusalem).  They were on Israel time since then; there might
+# have been a Military Governor's order about time zones, but I'm not aware
+# of any (such orders may have been issued semi-annually whenever summer
+# time was in effect, but maybe the legal aspect of time was just neglected).
+#
+# The Palestinian Authority was established in 1993, and got hold of most
+# towns in the West Bank and Gaza by 1995.  I know that in order to
+# demonstrate...independence, they have been switching to
+# summer time and back on a different schedule than Israel's, but I don't
+# know when this was started, or what algorithm is used (most likely the
+# Jordanian one).
+#
+# To summarize, the table should probably look something like that:
+#
+# Area \ when | 1918-1947 | 1948-1967 | 1967-1995 | 1996-
+# ------------+-----------+-----------+-----------+-----------
+# Israel      | Zion      | Zion      | Zion      | Zion
+# West bank   | Zion      | Jordan    | Zion      | Jordan
+# Gaza        | Zion      | Egypt     | Zion      | Jordan
+#
+# I guess more info may be available from the PA's web page (if/when they
+# have one).
+
+# From Paul Eggert (1998-02-25):
+# Shanks writes that Gaza did not observe DST until 1957, but we'll go
+# with Shapir and assume that it observed DST from 1940 through 1947,
+# and that it used Jordanian rules starting in 1996.
+# We don't yet need a separate entry for the West Bank, since
+# the only differences between it and Gaza that we know about
+# occurred before our cutoff date of 1970.
+# However, as we get more information, we may need to add entries
+# for parts of the West Bank as they transitioned from Israel's rules
+# to Palestine's rules.  If you have more info about this, please
+# send it to tz@elsie.nci.nih.gov for incorporation into future editions.
+
+# From IINS News Service - Israel - 1998-03-23 10:38:07 Israel time,
+# forwarded by Ephraim Silverberg:
+#
+# Despite the fact that Israel changed over to daylight savings time
+# last week, the PLO Authority (PA) has decided not to turn its clocks
+# one-hour forward at this time.  As a sign of independence from Israeli rule,
+# the PA has decided to implement DST in April.
+
+# From Paul Eggert (1999-09-20):
+# Daoud Kuttab writes in
+# <a href="http://www.jpost.com/com/Archive/22.Apr.1999/Opinion/Article-2.html">
+# Holiday havoc
+# </a> (Jerusalem Post, 1999-04-22) that
+# the Palestinian National Authority changed to DST on 1999-04-15.
+# I vaguely recall that they switch back in October (sorry, forgot the source).
+# For now, let's assume that the spring switch was at 24:00,
+# and that they switch at 0:00 on the 3rd Fridays of April and October.
+
+# The rules for Egypt are stolen from the `africa' file.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
 Rule EgyptAsia	1957	1958	-	Oct	 1	0:00	0	-
@@ -823,17 +1097,26 @@ Rule EgyptAsia	1958	only	-	May	 1	0:00	1:00	S
 Rule EgyptAsia	1959	1967	-	May	 1	1:00	1:00	S
 Rule EgyptAsia	1959	1965	-	Sep	30	3:00	0	-
 Rule EgyptAsia	1966	only	-	Oct	 1	3:00	0	-
+
+Rule Palestine	1999	max	-	Apr	Fri>=15	0:00	1:00	S
+Rule Palestine	1999	max	-	Oct	Fri>=15	0:00	0	-
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
-			2:00	-	EET	1957 May 10
-			2:00 EgyptAsia	EE%sT	1967 Jun 30
-			2:00	Zion	I%sT
+			2:00	Zion	EET	1948 May 15
+			2:00 EgyptAsia	EE%sT	1967 Jun  5
+			2:00	Zion	I%sT	1996
+			2:00	Jordan	EE%sT	1999
+			2:00 Palestine	EE%sT
 
 # Paracel Is
 # no information
 
 # Philippines
-# Howse writes (p 162) that until 1844 the Philippines kept American date.
+# On 1844-08-16, Narciso Claveria, governor-general of the
+# Philippines, issued a proclamation announcing that 1844-12-30 was to
+# be immediately followed by 1845-01-01.  Robert H. van Gent has a
+# transcript of the decree in <http://www.phys.uu.nl/~vgent/idl/idl.htm>.
 # The rest of this data is from Shanks.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Phil	1936	only	-	Nov	1	0:00	1:00	S
@@ -843,7 +1126,7 @@ Rule	Phil	1954	only	-	Jul	1	0:00	0	-
 Rule	Phil	1978	only	-	Mar	22	0:00	1:00	S
 Rule	Phil	1978	only	-	Sep	21	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Manila	-15:56:00 -	LMT	1844
+Zone	Asia/Manila	-15:56:00 -	LMT	1844 Dec 31
 			8:04:00 -	LMT	1899 May 11
 			8:00	Phil	PH%sT	1942 May
 			9:00	-	JST	1944 Nov
@@ -851,7 +1134,7 @@ Zone	Asia/Manila	-15:56:00 -	LMT	1844
 
 # Qatar
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Qatar	3:26:08 -	LMT	1920		# Al Dawhah
+Zone	Asia/Qatar	3:26:08 -	LMT	1920	# Al Dawhah / Doha
 			4:00	-	GST	1972 Jun
 			3:00	-	AST
 
@@ -877,19 +1160,29 @@ Zone	Asia/Singapore	6:55:24 -	LMT	1880
 
 # Sri Lanka
 # From Paul Eggert (1996-09-03):
-# <URL:http://www.virtual-pc.com/lankaweb/news/items/240596-2.html> (1996-05-24)
+# "Sri Lanka advances clock by an hour to avoid blackout"
+# (www.virtual-pc.com/lankaweb/news/items/240596-2.html, 1996-05-24,
+# no longer available as of 1999-08-17)
 # reported ``the country's standard time will be put forward by one hour at
 # midnight Friday (1830 GMT) `in the light of the present power crisis'.''
-# Transitions before 1996 are from Shanks (1991).
+#
+# From Dharmasiri Senanayake, Sri Lanka Media Minister (1996-10-24), as quoted
+# by Shamindra in
+# <a href="news:54rka5$m5h@mtinsc01-mgt.ops.worldnet.att.net">
+# Daily News - Hot News Section (1996-10-26)
+# </a>:
+# With effect from 12.30 a.m. on 26th October 1996
+# Sri Lanka will be six (06) hours ahead of GMT.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Colombo	5:19:24 -	LMT	1880
-			5:20	-	CEYT	1906	# Ceylon Time
+			5:19:32	-	MMT	1906	# Moratuwa Mean Time
 			5:30	-	IST	1942 Jan  5
 			5:30	0:30	IHST	1942 Sep
 			5:30	1:00	IST	1945 Oct 16 2:00
 			5:30	-	IST	1996 May 25 0:00
-			6:30	-	LKT	# Sri Lanka Time
+			6:30	-	LKT	1996 Oct 26 0:30
+			6:00	-	LKT
 
 # Syria
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -921,20 +1214,25 @@ Rule	Syria	1991	1992	-	Oct	 1	0:00	0	-
 Rule	Syria	1992	only	-	Apr	 8	0:00	1:00	S
 Rule	Syria	1993	only	-	Mar	26	0:00	1:00	S
 Rule	Syria	1993	only	-	Sep	25	0:00	0	-
-# IATA SSIM (1996-09) says 1997-03-31; assume that it should be 1997-04-01.
-Rule	Syria	1994	max	-	Apr	 1	0:00	1:00	S
+# IATA SSIM (1998-02) says 1998-04-02;
+# (1998-09) says 1999-03-29 and 1999-09-29; (1999-02) says 1999-04-02,
+# 2000-04-02, and 2001-04-02; (1999-09) says 2000-03-31 and 2001-03-31;
+# ignore all these claims and go with Shanks.
+Rule	Syria	1994	1996	-	Apr	 1	0:00	1:00	S
 Rule	Syria	1994	max	-	Oct	 1	0:00	0	-
+Rule	Syria	1997	1998	-	Mar	lastMon	0:00	1:00	S
+Rule	Syria	1999	max	-	Apr	 1	0:00	1:00	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Damascus	2:25:12 -	LMT	1920
+Zone	Asia/Damascus	2:25:12 -	LMT	1920	# Dimashq
 			2:00	Syria	EE%sT
 
 # Tajikistan
+# From Shanks.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Dushanbe	4:35:12 -	LMT	1924 May  2
-			5:00	-	DUST	1957 Mar    # Dushanbe Time
+			5:00	-	DUST	1930 Jun 21 # Dushanbe Time
 			6:00 RussiaAsia DUS%sT	1991 Mar 31 2:00s
-			5:00	1:00	DUSST	1991 Sep  9 # independence
-			5:00 RussiaAsia	TJ%sT	1992
+			5:00	1:00	DUSST	1991 Sep  9 2:00s
 			5:00	-	TJT		    # Tajikistan Time
 
 # Thailand
@@ -944,14 +1242,14 @@ Zone	Asia/Bangkok	6:42:04	-	LMT	1880
 			7:00	-	ICT
 
 # Turkmenistan
+# From Shanks.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Asia/Ashkhabad	3:53:32 -	LMT	1924 May  2 # or Ashgabat
-			4:00	-	ASHT	1957 Mar    # Ashkhabad Time
-			5:00 RussiaAsia ASH%sT	1991 Mar 31 2:00s
-			4:00	1:00	ASHST	1991 Sep 29 2:00s
-			4:00	-	ASHT	1991 Oct 27 # independence
-			4:00	-	TMT	1992 Jan 19 2:00s
-			5:00	-	TMT	# Turkmenistan Time
+Zone	Asia/Ashgabat	3:53:32 -	LMT	1924 May  2 # or Ashkhabad
+			4:00	-	ASHT	1930 Jun 21 # Ashkhabad Time
+			5:00 RussiaAsia	ASH%sT	1991 Mar 31 2:00
+			4:00 RussiaAsia	ASH%sT	1991 Oct 27 # independence
+			4:00 RussiaAsia TM%sT	1992 Jan 19 2:00
+			5:00	-	TMT
 
 # United Arab Emirates
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -960,23 +1258,28 @@ Zone	Asia/Dubai	3:41:12 -	LMT	1920
 
 # Uzbekistan
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Samarkand	4:27:12 -	LMT	1924 May  2
+			4:00	-	SAMT	1930 Jun 21 # Samarkand Time
+			5:00	-	SAMT	1981 Apr  1
+			5:00	1:00	SAMST	1981 Oct  1
+			6:00 RussiaAsia TAS%sT	1991 Mar 31 2:00 # Tashkent Time
+			5:00 RussiaAsia	TAS%sT	1991 Sep  1 # independence
+			5:00 RussiaAsia	UZ%sT	1992
+			5:00 RussiaAsia	UZ%sT	1993
+			5:00	-	UZT
 Zone	Asia/Tashkent	4:37:12 -	LMT	1924 May  2
-			5:00	-	TAST	1957 Mar    # Tashkent Time
+			5:00	-	TAST	1930 Jun 21 # Tashkent Time
 			6:00 RussiaAsia TAS%sT	1991 Mar 31 2:00s
-			5:00	1:00	TASST	1991 Sep 29 2:00s
-			5:00	-	UZT		    # Uzbekistan Time
-# Shanks has Tashkent using DST after 1991, but usno1995 says they don't.
-# Guess no DST after 1991.
-# <URL:http://www.odci.gov/cia/publications/95fact/802389h.gif> (1995)
-# says that Uzbekistan has two time zones, but a cable
-# <URL:http://www.itaiep.doc.gov/bisnis/cables/960510uz.html> (1996-05-10)
-# from the American Embassy in Tashkent implies that they have just one.
+			5:00 RussiaAsia	TAS%sT	1991 Sep  1 # independence
+			5:00 RussiaAsia	UZ%sT	1992
+			5:00 RussiaAsia	UZ%sT	1993
+			5:00	-	UZT
 
 # Vietnam
 # From Paul Eggert <eggert@twinsun.com> (1993-11-18):
 # Saigon's official name is Thanh-Pho Ho Chi Minh, but it's too long.
 # We'll stick with the traditional name for now.
-# From Shanks (1991):
+# From Shanks:
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Saigon	7:06:40 -	LMT	1906 Jun  9
 			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
diff --git a/zic.tproj/datfiles/australasia b/zic.tproj/datfiles/australasia
index e1e567a..f0db6a9 100644
--- a/zic.tproj/datfiles/australasia
+++ b/zic.tproj/datfiles/australasia
@@ -1,7 +1,6 @@
-#	$OpenBSD: australasia,v 1.5 1997/01/14 04:36:50 millert Exp $
-# @(#)australasia	7.31
+# @(#)australasia	7.64
 # This file also includes Pacific islands.
-
+# $FreeBSD: src/share/zoneinfo/australasia,v 1.19 2001/05/01 14:10:12 schweikh Exp $
 # Notes are at the end of this file
 
 ###############################################################################
@@ -9,26 +8,26 @@
 # Australia
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# Shanks gives 1917 Jan 1 0:01; go with Whitman (and guess 2:00).
-Rule	Aus	1916	only	-	Oct	 1	2:00	1:00	-
+Rule	Aus	1917	only	-	Jan	 1	0:01	1:00	-
 Rule	Aus	1917	only	-	Mar	25	2:00	0	-
 Rule	Aus	1942	only	-	Jan	 1	2:00	1:00	-
 Rule	Aus	1942	only	-	Mar	29	2:00	0	-
 Rule	Aus	1942	only	-	Sep	27	2:00	1:00	-
 Rule	Aus	1943	1944	-	Mar	lastSun	2:00	0	-
 Rule	Aus	1943	only	-	Oct	 3	2:00	1:00	-
-# Whitman says W Australia didn't use DST in 1943/1944, and that
-# 1944/1945 was just like 1943/1944; go with Shanks.
+# Go with Whitman and the Australian National Standards Commission, which
+# says W Australia didn't use DST in 1943/1944.  Ignore Whitman's claim that
+# 1944/1945 was just like 1943/1944.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 # Northern Territory
 Zone Australia/Darwin	 8:43:20 -	LMT	1895 Feb
-			 9:30	-	CST	1917 Jan 1 0:01
+			 9:00	-	CST	1899 May
 			 9:30	Aus	CST
 # Western Australia
 Zone Australia/Perth	 7:43:24 -	LMT	1895 Dec
-			 8:00	-	WST	1917 Jan 1 0:01
-			 8:00	Aus	WST	1974 Oct lastSun 2:00s
+			 8:00	Aus	WST	1943 Jul
+			 8:00	-	WST	1974 Oct lastSun 2:00s
 			 8:00	1:00	WST	1975 Mar Sun>=1 2:00s
 			 8:00	-	WST	1983 Oct lastSun 2:00s
 			 8:00	1:00	WST	1984 Mar Sun>=1 2:00s
@@ -49,19 +48,18 @@ Zone Australia/Perth	 7:43:24 -	LMT	1895 Dec
 # so use Lindeman.
 #
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AQ	1971	only	-	Oct	lastSun	2:00s	1:00	-
+Rule	AQ	1972	only	-	Feb	lastSun	2:00s	0	-
 Rule	AQ	1989	1991	-	Oct	lastSun	2:00s	1:00	-
 Rule	AQ	1990	1992	-	Mar	Sun>=1	2:00s	0	-
-Rule	Holiday	1989	1993	-	Oct	lastSun	2:00s	1:00	-
-Rule	Holiday	1990	1994	-	Mar	Sun>=1	2:00s	0	-
+Rule	Holiday	1992	1993	-	Oct	lastSun	2:00s	1:00	-
+Rule	Holiday	1993	1994	-	Mar	Sun>=1	2:00s	0	-
 Zone Australia/Brisbane	10:12:08 -	LMT	1895
-			10:00	-	EST	1917 Jan 1 0:01
-			10:00	Aus	EST	1971 Oct lastSun 2:00s
-			10:00	1:00	EST	1972 Feb lastSun 2:00s
+			10:00	Aus	EST	1971
 			10:00	AQ	EST
 Zone Australia/Lindeman  9:55:56 -	LMT	1895
-			10:00	-	EST	1917 Jan 1 0:01
-			10:00	Aus	EST	1971 Oct lastSun 2:00s
-			10:00	1:00	EST	1972 Feb lastSun 2:00s
+			10:00	Aus	EST	1971
+			10:00	AQ	EST	1992 Jul
 			10:00	Holiday	EST
 
 # South Australia
@@ -72,51 +70,58 @@ Rule	AS	1987	max	-	Oct	lastSun	2:00s	1:00	-
 Rule	AS	1972	only	-	Feb	27	2:00s	0	-
 Rule	AS	1973	1985	-	Mar	Sun>=1	2:00s	0	-
 Rule	AS	1986	1989	-	Mar	Sun>=15	2:00s	0	-
-Rule	AS	1990	1994	even	Mar	Sun>=18	2:00s	0	-
-Rule	AS	1990	1994	odd	Mar	Sun>=1	2:00s	0	-
+Rule	AS	1990	only	-	Mar	Sun>=18	2:00s	0	-
+Rule	AS	1991	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AS	1992	only	-	Mar	Sun>=18	2:00s	0	-
+Rule	AS	1993	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AS	1994	only	-	Mar	Sun>=18	2:00s	0	-
 Rule	AS	1995	max	-	Mar	lastSun	2:00s	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Australia/Adelaide	9:14:20 -	LMT	1895 Feb
 			9:00	-	CST	1899 May
-			9:30	-	CST	1917 Jan 1 0:01
-			9:30	Aus	CST	1971 Oct lastSun 2:00s
+			9:30	Aus	CST	1971
 			9:30	AS	CST
 
 # Tasmania
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	AT	1967	only	-	Oct	1	2:00s	1:00	-
-Rule	AT	1968	only	-	Mar	31	2:00s	0	-
+Rule	AT	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	AT	1968	only	-	Mar	lastSun	2:00s	0	-
 Rule	AT	1968	1985	-	Oct	lastSun	2:00s	1:00	-
 Rule	AT	1969	1971	-	Mar	Sun>=8	2:00s	0	-
-Rule	AT	1972	only	-	Feb	27	2:00s	0	-
+Rule	AT	1972	only	-	Feb	lastSun	2:00s	0	-
 Rule	AT	1973	1981	-	Mar	Sun>=1	2:00s	0	-
 Rule	AT	1982	1983	-	Mar	lastSun	2:00s	0	-
 Rule	AT	1984	1986	-	Mar	Sun>=1	2:00s	0	-
-Rule	AT	1986	only	-	Oct	19	2:00s	1:00	-
+Rule	AT	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
 Rule	AT	1987	1990	-	Mar	Sun>=15	2:00s	0	-
-Rule	AT	1987	1990	-	Oct	lastSun	2:00s	1:00	-
-Rule	AT	1991	max	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	AT	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
+Rule	AT	1988	1990	-	Oct	lastSun	2:00s	1:00	-
+Rule	AT	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
 Rule	AT	1991	max	-	Mar	lastSun	2:00s	0	-
+Rule	AT	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	AT	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Australia/Hobart	9:49:16	-	LMT	1895 Sep
-			10:00	-	EST	1917 Jan 1 0:01
-			10:00	Aus	EST	1967 Oct 1 2:00s
+			10:00	-	EST	1916 Oct 1 2:00
+			10:00	1:00	EST	1917 Feb
+			10:00	Aus	EST	1967
 			10:00	AT	EST
 
 # Victoria
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	AV	1971	1985	-	Oct	lastSun	2:00s	1:00	-
-Rule	AV	1972	only	-	Feb	27	2:00s	0	-
+Rule	AV	1972	only	-	Feb	lastSun	2:00s	0	-
 Rule	AV	1973	1985	-	Mar	Sun>=1	2:00s	0	-
 Rule	AV	1986	1990	-	Mar	Sun>=15	2:00s	0	-
-Rule	AV	1986	only	-	Oct	19	2:00s	1:00	-
-Rule	AV	1987	max	-	Oct	lastSun	2:00s	1:00	-
+Rule	AV	1986	1987	-	Oct	Sun>=15	2:00s	1:00	-
+Rule	AV	1988	1999	-	Oct	lastSun	2:00s	1:00	-
 Rule	AV	1991	1994	-	Mar	Sun>=1	2:00s	0	-
 Rule	AV	1995	max	-	Mar	lastSun	2:00s	0	-
+Rule	AV	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	AV	2001	max	-	Oct	lastSun	2:00s	1:00	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Australia/Melbourne 9:39:52 -	LMT	1895 Feb
-			10:00	-	EST	1917 Jan 1 0:01
-			10:00	Aus	EST	1971 Oct 31 2:00s
+			10:00	Aus	EST	1971
 			10:00	AV	EST
 
 # New South Wales
@@ -128,57 +133,64 @@ Rule	AN	1982	only	-	Apr	Sun>=1	2:00s	0	-
 Rule	AN	1983	1985	-	Mar	Sun>=1	2:00s	0	-
 Rule	AN	1986	1989	-	Mar	Sun>=15	2:00s	0	-
 Rule	AN	1986	only	-	Oct	19	2:00s	1:00	-
-Rule	AN	1987	max	-	Oct	lastSun	2:00s	1:00	-
+Rule	AN	1987	1999	-	Oct	lastSun	2:00s	1:00	-
 Rule	AN	1990	1995	-	Mar	Sun>=1	2:00s	0	-
 Rule	AN	1996	max	-	Mar	lastSun	2:00s	0	-
+Rule	AN	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	AN	2001	max	-	Oct	lastSun	2:00s	1:00	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Australia/Sydney	10:04:52 -	LMT	1895 Feb
-			10:00	-	EST	1917 Jan 1 0:01
-			10:00	Aus	EST	1971 Oct 31 2:00s
+			10:00	Aus	EST	1971
 			10:00	AN	EST
 Zone Australia/Broken_Hill 9:25:48 -	LMT	1895 Feb
 			10:00	-	EST	1896 Aug 23
 			9:00	-	CST	1899 May
-			9:30	-	CST	1917 Jan 1 0:01
-			9:30	Aus	CST	1971 Oct 31 2:00s
-			9:30	AN	CST
+			9:30	Aus	CST	1971
+			9:30	AN	CST	2000
+			9:30	AS	CST
 
 # Lord Howe Island
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	LH	1981	1984	-	Oct	lastSun	2:00s	1:00	-
-Rule	LH	1982	1985	-	Mar	Sun>=1	2:00s	0	-
-Rule	LH	1985	only	-	Oct	lastSun	2:00s	0:30	-
-Rule	LH	1986	1989	-	Mar	Sun>=15	2:00s	0	-
-Rule	LH	1986	only	-	Oct	19	2:00s	0:30	-
-Rule	LH	1987	max	-	Oct	lastSun	2:00s	0:30	-
-Rule	LH	1990	1995	-	Mar	Sun>=1	2:00s	0	-
-Rule	LH	1996	max	-	Mar	lastSun	2:00s	0	-
+Rule	LH	1981	1984	-	Oct	lastSun	2:00	1:00	-
+Rule	LH	1982	1985	-	Mar	Sun>=1	2:00	0	-
+Rule	LH	1985	only	-	Oct	lastSun	2:00	0:30	-
+Rule	LH	1986	1989	-	Mar	Sun>=15	2:00	0	-
+Rule	LH	1986	only	-	Oct	19	2:00	0:30	-
+Rule	LH	1987	1999	-	Oct	lastSun	2:00	0:30	-
+Rule	LH	1990	1995	-	Mar	Sun>=1	2:00	0	-
+Rule	LH	1996	max	-	Mar	lastSun	2:00	0	-
+Rule	LH	2000	only	-	Aug	lastSun	2:00	0:30	-
+Rule	LH	2001	max	-	Oct	lastSun	2:00	0:30	-
 Zone Australia/Lord_Howe 10:36:20 -	LMT	1895 Feb
 			10:00	-	EST	1981 Mar
 			10:30	LH	LHST
 
 # Australian miscellany
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Indian/Christmas	7:02:52 -	LMT	1895 Feb
-			7:00	-	CXT	# Christmas Island Time
 #
 # Ashmore Is, Cartier
 # no indigenous inhabitants; only seasonal caretakers
-# no information; probably like Australia/Perth
+# like Australia/Perth, says Turner
 #
 # Coral Sea Is
 # no indigenous inhabitants; only meteorologists
 # no information
 #
-# Macquarie, Manihiki, Penrhyn, Rakehanga
-# no information
+# Macquarie
+# permanent occupation (scientific station) since 1948;
+# sealing and penguin oil station operated 1888/1917
+# like Australia/Hobart, says Turner
 
+# Christmas
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Christmas	7:02:52 -	LMT	1895 Feb
+			7:00	-	CXT	# Christmas Island Time
 
 # Cook Is
+# From Shanks:
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Cook	1978	only	-	Nov	12	0:00	0:30	HS
-Rule	Cook	1979	max	-	Mar	Sun>=1	0:00	0	-
-Rule	Cook	1979	max	-	Oct	lastSun	0:00	0:30	HS
+Rule	Cook	1979	1991	-	Mar	Sun>=1	0:00	0	-
+Rule	Cook	1979	1990	-	Oct	lastSun	0:00	0:30	HS
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Pacific/Rarotonga	-10:39:04 -	LMT	1901		# Avarua
 			-10:30	-	CKT	1978 Nov 12	# Cook Is Time
@@ -190,9 +202,12 @@ Zone Pacific/Rarotonga	-10:39:04 -	LMT	1901		# Avarua
 Zone	Indian/Cocos	6:30	-	CCT	# Cocos Islands Time
 
 # Fiji
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Fiji	1998	1999	-	Nov	Sun>=1	2:00	1:00	S
+Rule	Fiji	1999	2000	-	Feb	lastSun	3:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
-			12:00	-	FJT	# Fiji Time
+			12:00	Fiji	FJ%sT	# Fiji Time
 
 # French Polynesia
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -202,26 +217,15 @@ Zone	Pacific/Marquesas -9:18:00 -	LMT	1912 Oct
 			 -9:30	-	MART	# Marquesas Time
 Zone	Pacific/Tahiti	 -9:58:16 -	LMT	1912 Oct	# Papeete
 			-10:00	-	TAHT	# Tahiti Time
+# Clipperton (near North America) is administered from French Polynesia;
+# it is uninhabited.
 
 # Guam
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Guam	 9:39:00 -	LMT	1901		# Agana
-			10:00	-	GST
-
-# Howland, Baker
-# uninhabited since World War II
-# no information; was probably like Pacific/Pago_Pago
-
-# Jarvis
-# uninhabited since 1958
-# no information; was probably like Pacific/Kiritimati
-
-# Johnston
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Johnston	-10:00	-	HST
-
-# Kingman
-# uninhabited
+Zone	Pacific/Guam	-14:21:00 -	LMT	1844 Dec 31
+			 9:39:00 -	LMT	1901		# Agana
+			10:00	-	GST	2000 Dec 23	# Guam
+			10:00	-	ChST	# Chamorro Standard Time
 
 # Kiribati
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -238,9 +242,11 @@ Zone Pacific/Kiritimati	-10:29:20 -	LMT	1901
 
 # N Mariana Is
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Saipan	 9:43:00 -	LMT	1901
+Zone Pacific/Saipan	-14:17:00 -	LMT	1844 Dec 31
+			 9:43:00 -	LMT	1901
 			 9:00	-	MPT	1969 Oct # N Mariana Is Time
-			10:00	-	MPT
+			10:00	-	MPT	2000 Dec 23
+			10:00	-	ChST	# Chamorro Standard Time
 
 # Marshall Is
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -262,8 +268,9 @@ Zone Pacific/Truk	10:07:08 -	LMT	1901
 Zone Pacific/Ponape	10:32:52 -	LMT	1901		# Kolonia
 			11:00	-	PONT			# Ponape Time
 Zone Pacific/Kosrae	10:51:56 -	LMT	1901
-			11:00	-	PONT	1969 Oct
-			12:00	-	KOST			# Kosrae Time
+			11:00	-	KOST	1969 Oct	# Kosrae Time
+			12:00	-	KOST	1999
+			11:00	-	KOST
 
 # Nauru
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -277,6 +284,9 @@ Zone	Pacific/Nauru	11:07:40 -	LMT	1921 Jan 15	# Uaobe
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	NC	1977	1978	-	Dec	Sun>=1	0:00	1:00	S
 Rule	NC	1978	1979	-	Feb	27	0:00	0	-
+Rule	NC	1996	only	-	Dec	 1	2:00s	1:00	S
+# Shanks says the following was at 2:00; go with IATA.
+Rule	NC	1997	only	-	Mar	 2	2:00s	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Pacific/Noumea	11:05:48 -	LMT	1912 Jan 13
 			11:00	NC	NC%sT
@@ -295,7 +305,7 @@ Rule	NZ	1928	only	-	Nov	 4	2:00	0:30	HD
 Rule	NZ	1929	only	-	Oct	30	2:00	0:30	HD
 Rule	NZ	1930	1933	-	Mar	Sun>=15	2:00	0	S
 Rule	NZ	1930	1933	-	Oct	Sun>=8	2:00	0:30	HD
-# Whitman says DST went on and off during war years, and the base GMT offset
+# Whitman says DST went on and off during war years, and the base UT offset
 # didn't change until 1945 Apr 30; go with Shanks.
 Rule	NZ	1934	1940	-	Apr	lastSun	2:00	0	S
 Rule	NZ	1934	1939	-	Sep	lastSun	2:00	0:30	HD
@@ -315,8 +325,15 @@ Zone Pacific/Auckland	11:39:04 -	LMT	1868
 Zone Pacific/Chatham	12:45	Chatham	CHA%sT
 
 
-# Antipodes Is, Kermadec Is
-# uninhabited except by research personnel; probably like Pacific/Auckland
+# Auckland Is
+# uninhabited; Maori and Moriori, colonial settlers, pastoralists, sealers,
+# and scientific personnel have wintered
+
+# Campbell I
+# minor whaling stations operated 1909/1914
+# scientific station operated 1941/1995;
+# previously whalers, sealers, pastoralists, and scientific personnel wintered
+# was probably like Pacific/Auckland
 
 ###############################################################################
 
@@ -334,14 +351,11 @@ Zone	Pacific/Norfolk	11:11:52 -	LMT	1901		# Kingston
 			11:12	-	NMT	1951	# Norfolk Mean Time
 			11:30	-	NFT		# Norfolk Time
 
-# Palau
+# Palau (Belau)
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Pacific/Palau	8:57:56 -	LMT	1901		# Koror
 			9:00	-	PWT	# Palau Time
 
-# Palmyra
-# uninhabited since World War II; was probably like Pacific/Kiritimati
-
 # Papua New Guinea
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Pacific/Port_Moresby 9:48:40 -	LMT	1880
@@ -351,7 +365,8 @@ Zone Pacific/Port_Moresby 9:48:40 -	LMT	1880
 # Pitcairn
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Pacific/Pitcairn	-8:40:20 -	LMT	1901		# Adamstown
-			-8:30	-	PNT	# Pitcairn Time
+			-8:30	-	PNT	1998 Apr 27 00:00
+			-8:00	-	PST	# Pitcairn Standard Time
 
 # American Samoa
 Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
@@ -379,16 +394,55 @@ Zone	Pacific/Fakaofo	-11:24:56 -	LMT	1901
 			-10:00	-	TKT	# Tokelau Time
 
 # Tonga
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Tonga	1999	only	-	Oct	 7	2:00s	1:00	S
+Rule	Tonga	2000	only	-	Mar	19	2:00s	0	-
+Rule	Tonga	2000	only	-	Nov	 4	2:00s	1:00	S
+Rule	Tonga	2001	only	-	Jan	27	2:00s	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Pacific/Tongatapu	12:19:20 -	LMT	1901
-			12:20	-	TOT	1968 Oct # Tonga Time
-			13:00	-	TOT
+			12:20	-	TOT	1941 # Tonga Time
+			13:00	-	TOT	1999
+			13:00	Tonga	TO%sT
 
 # Tuvalu
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Pacific/Funafuti	11:56:52 -	LMT	1901
 			12:00	-	TVT	# Tuvalu Time
 
+
+# US minor outlying islands
+
+# Howland, Baker
+# uninhabited since World War II
+# no information; was probably like Pacific/Pago_Pago
+
+# Jarvis
+# uninhabited since 1958
+# no information; was probably like Pacific/Kiritimati
+
+# Johnston
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Johnston	-10:00	-	HST
+
+# Kingman
+# uninhabited
+
+# Midway
+Zone Pacific/Midway	-11:49:28 -	LMT	1901
+			-11:00	-	NST	1967 Apr	# N=Nome
+			-11:00	-	BST	1983 Nov 30	# B=Bering
+			-11:00	-	SST			# S=Samoa
+
+# Palmyra
+# uninhabited since World War II; was probably like Pacific/Kiritimati
+
+# Wake
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Wake	11:06:28 -	LMT	1901
+			12:00	-	WAKT	# Wake Time
+
+
 # Vanuatu
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Vanuatu	1983	only	-	Sep	25	0:00	1:00	S
@@ -401,11 +455,6 @@ Rule	Vanuatu	1992	only	-	Oct	Sun>=23	0:00	1:00	S
 Zone	Pacific/Efate	11:13:16 -	LMT	1912 Jan 13		# Vila
 			11:00	Vanuatu	VU%sT	# Vanuatu Time
 
-# Wake
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Wake	11:06:28 -	LMT	1901
-			12:00	-	WAKT	# Wake Time
-
 # Wallis and Futuna
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Pacific/Wallis	12:15:20 -	LMT	1901
@@ -419,12 +468,12 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 # go ahead and edit the file (and please send any changes to
 # tz@elsie.nci.nih.gov for general use in the future).
 
-# From Paul Eggert <eggert@twinsun.com> (1996-11-22):
+# From Paul Eggert <eggert@twinsun.com> (1999-10-29):
 # A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
+# Thomas G. Shanks, The International Atlas (5th edition),
+# San Diego: ACS Publications, Inc. (1999).
 #
-# Gwillim Law <LAW@encmail.encompass.com> writes that a good source
+# Gwillim Law <Gwil_Law@bridge-point.com> writes that a good source
 # for recent time zone data is the International Air Transport
 # Association's Standard Schedules Information Manual (IATA SSIM),
 # published semiannually.  Law sent in several helpful summaries
@@ -438,8 +487,7 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 # I found in the UCLA library.
 #
 # A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and the discovery of the longitude,
-# Oxford University Press (1980).
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
 # I invented the abbreviations marked `*' in the following table;
 # the rest are from earlier versions of this file, or from other sources.
@@ -450,22 +498,25 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 #	  9:00	JST	Japan
 #	  9:30	CST CST	Central Australia
 #	 10:00	EST EST	Eastern Australia
-#	 10:00	GST	Guam
+#	 10:00	ChST	Chamorro
 #	 10:30	LHST LHST Lord Howe*
 #	 12:00	NZST NZDT New Zealand
 #	 12:45	CHAST CHADT Chatham*
 #	-11:00	SST	Samoa
 #	-10:00	HST	Hawaii
+#	- 8:00	PST	Pitcairn*
 #
 # See the `northamerica' file for Hawaii.
 # See the `southamerica' file for Easter I and the Galapagos Is.
-#
-# See the `africa' file for time zone naming and abbreviation conventions.
 
 ###############################################################################
 
 # Australia
 
+# <a href="http://www.dstc.qut.edu.au/DST/marg/daylight.html">
+# Australia's Daylight Saving Times
+# </a>, by Margaret Turner, summarizes daylight saving issues in Australia.
+
 # From John Mackin (1991-03-06):
 # We in Australia have _never_ referred to DST as `daylight' time.
 # It is called `summer' time.  Now by a happy coincidence, `summer'
@@ -498,6 +549,25 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 # and perhaps the newspaper's `2:00' is referring to standard time.
 # For now we'll continue to assume 2:00s for changes since 1960.
 
+# From Eric Ulevik <eau@zip.com.au> (1998-01-05):
+#
+# Here are some URLs to Australian time legislation. These URLs are stable,
+# and should probably be included in the data file. There are probably more
+# relevant entries in this database.
+#
+# NSW (including LHI and Broken Hill):
+# <a href="http://www.austlii.edu.au/au/legis/nsw/consol_act/sta1987137/index.html">
+# Standard Time Act 1987 (updated 1995-04-04)
+# </a>
+# ACT
+# <a href="http://www.austlii.edu.au/au/legis/act/consol_act/stasta1972279/index.html">
+# Standard Time and Summer Time Act 1972
+# </a>
+# SA
+# <a href="http://www.austlii.edu.au/au/legis/sa/consol_act/sta1898137/index.html">
+# Standard Time Act, 1898
+# </a>
+
 # Northern Territory
 
 # From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
@@ -543,6 +613,11 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 # The 1992 ending date used in the rules is a best guess;
 # it matches what was used in the past.
 
+# <a href="http://www.bom.gov.au/faq/faqgen.htm">
+# The Australian Bureau of Meteorology FAQ
+# </a> (1999-09-27) writes that Giles Meteorological Station uses
+# South Australian time even though it's located in Western Australia.
+
 # Queensland
 # From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
 # #   The state of QUEENSLAND.. [ Courtesy Qld. Dept Premier Econ&Trade Devel ]
@@ -654,66 +729,32 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 
 # Tasmania
 
-# From Bradley White (1991-03-04):
-# A recent excerpt from an Australian newspaper...
-# ...Tasmania will revert to Australian Eastern Standard Time on March 31...
-
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# The rules for 1967 through 1991 were reported by George Shepherd
+# via Simon Woodhead via Robert Elz (1991-03-06):
 # #  The state of TASMANIA.. [Courtesy Tasmanian Dept of Premier + Cabinet ]
 # #					[ Nov 1990 ]
-# ...
-# Zone	Australia/Tasmania	10:00	AT	%sST
-# ...
-# Rule	AT	1967	only	-	Oct	Sun>=1	2:00	1:00	D
-# Rule	AT	1968	only	-	Mar	lastSun	3:00	0	E
-# Rule	AT	1968	1985	-	Oct	lastSun	2:00	1:00	D
-# Rule	AT	1969	1971	-	Mar	Sun>=8	3:00	0	E
-# Rule	AT	1972	only	-	Feb	lastSun	3:00	0	E
-# Rule	AT	1973	1981	-	Mar	Sun>=1	3:00	0	E
-# Rule	AT	1982	1983	-	Mar	lastSun	3:00	0	E
-# Rule	AT	1984	1986	-	Mar	Sun>=1	3:00	0	E
-# Rule	AT	1986	only	-	Oct	Sun>=15	2:00	1:00	D
-# Rule	AT	1987	1990	-	Mar	Sun>=15	3:00	0	E
-# Rule	AT	1987	only	-	Oct	Sun>=22	2:00	1:00	D
-# Rule	AT	1988	1990	-	Oct	lastSun	2:00	1:00	D
-# Rule	AT	1991	max	-	Oct	Sun>=1	2:00	1:00	D
-# Rule	AT	1991	max	-	Mar	lastSun	3:00	0	E
-
-# From Bill Hart via Alexander Dupuy and Guy Harris (1991-10-10):
-# My state Government in there eagerness to get a few more bucks for the
-# tourist industry industry decided to change the daylight savings times
-# yet again (we now have almost 6 months per year)...
-# ...
-# Rule  Oz      1986    1990    -       Oct     Sun<=24 2:00    1:00    -
-# Rule  Oz      1991    max     -       Oct     Sun>=1  2:00    1:00    -
-# ...
-# Rule  Oz      1987    1990    -       Mar     Sun<=21 3:00    0       -
-# Rule  Oz      1991    max     -       Mar     Sun<=31 3:00    0       -
 
 # From Bill Hart via Guy Harris (1991-10-10):
 # Oh yes, the new daylight savings rules are uniquely tasmanian, we have
 # 6 weeks a year now when we are out of sync with the rest of Australia
 # (but nothing new about that).
 
-# Victoria
+# From Alex Livingston (1999-10-04):
+# I heard on the ABC (Australian Broadcasting Corporation) radio news on the
+# (long) weekend that Tasmania, which usually goes its own way in this regard,
+# has decided to join with most of NSW, the ACT, and most of Victoria
+# (Australia) and start daylight saving on the last Sunday in August in 2000
+# instead of the first Sunday in October.
 
-# From Bradley White (1991-03-04):
-# A recent excerpt from an Australian newspaper...
-# ...Victoria...[has] agreed to end daylight saving at 3am tomorrow (March 3)...
+# Sim Alam (2000-07-03) reported a legal citation for the 2000/2001 rules:
+# http://www.thelaw.tas.gov.au/fragview/42++1968+GS3A@EN+2000070300
 
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# Victoria
+
+# The rules for 1971 through 1991 were reported by George Shepherd
+# via Simon Woodhead via Robert Elz (1991-03-06):
 # #   The state of VICTORIA.. [ Courtesy of Vic. Dept of Premier + Cabinet ]
 # #						[ Nov 1990 ]
-# ...
-# Zone	Australia/Victoria	10:00	AV	%sST
-# ...
-# Rule	AV	1971	1985	-	Oct	lastSun	2:00	1:00	D
-# Rule	AV	1972	only	-	Feb	lastSun	3:00	0	E
-# Rule	AV	1973	1985	-	Mar	Sun>=1	3:00	0	E
-# Rule	AV	1986	1990	-	Mar	Sun>=15	3:00	0	E
-# Rule	AV	1986	1987	-	Oct	Sun>=15	2:00	1:00	D
-# Rule	AV	1988	max	-	Oct	lastSun	2:00	1:00	D
-# Rule	AV	1991	max	-	Mar	Sun>=1	3:00	0	E
 
 # New South Wales
 
@@ -728,43 +769,80 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 #	legislation.  This is very important to understand.
 #	I have researched New South Wales time only...
 
-# From Dave Davey (1990-03-03):
-# Rule	NSW	1988	only	-	Mar	Sun>=1	3:00	0	-
-# Rule	NSW	1989	only	-	Mar	Sun<=21	3:00	0	-
-
-# From Bradley White (1991-03-04):
-# A recent excerpt from an Australian newspaper...
-# NSW...[has] agreed to end daylight saving at 3am tomorrow (March 3)...
-
-# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
-# # The state of NEW SOUTH WALES.. [confirmed by Attorney General's Dept N.S.W]
-# #					[ Dec 1990 ]
-# ...
-# Rule	 AN	1988	1989	-	Mar	Sun<=21	3:00	0	E
-# ...
-
-# From John Mackin (1991-03-09)
-# I have confirmed the accuracy of the historical data for NSW in the
-# file Robert forwarded
+# From Paul Eggert (1999-09-27):
+# The Information Service of the Australian National Standards Commission
+# <a href="http://www.nsc.gov.au/InfoServ/Ileaflet/il27.htm">
+# Daylight Saving
+# </a> page (1995-04) has an excellent overall history of Australian DST.
+# The Community Relations Division of the NSW Attorney General's Department
+# publishes a history of daylight saving in NSW.  See:
+# <a href="http://www.lawlink.nsw.gov.au/crd.nsf/pages/time2">
+# Lawlink NSW: Daylight Saving in New South Wales
+# </a>
+
+# From Eric Ulevik <eau@ozemail.com.au> (1999-05-26):
+# DST will start in NSW on the last Sunday of August, rather than the usual
+# October in 2000.  [See: Matthew Moore,
+# <a href="http://www.smh.com.au/news/9905/26/pageone/pageone4.html">
+# Two months more daylight saving
+# </a>
+# Sydney Morning Herald (1999-05-26).]
+
+# From Paul Eggert (1999-09-27):
+# See the following official NSW source:
+# <a href="http://dir.gis.nsw.gov.au/cgi-bin/genobject/document/other/daylightsaving/tigGmZ">
+# Daylight Saving in New South Wales.
+# </a>
+#
+# Narrabri Shire (NSW) council has announced it will ignore the extension of
+# daylight saving next year.  See:
+# <a href="http://abc.net.au/news/regionals/neweng/monthly/regeng-22jul1999-1.htm">
+# Narrabri Council to ignore daylight saving
+# </a> (1999-07-22).  For now, we'll wait to see if this really happens.
+#
+# Victoria will following NSW.  See:
+# <a href="http://abc.net.au/local/news/olympics/1999/07/item19990728112314_1.htm">
+# Vic to extend daylight saving
+# </a> (1999-07-28).
+#
+# However, South Australia rejected the DST request.  See:
+# <a href="http://abc.net.au/news/olympics/1999/07/item19990719151754_1.htm">
+# South Australia rejects Olympics daylight savings request
+# </a> (1999-07-19).
+#
+# Queensland also will not observe DST for the Olympics.  See:
+# <a href="http://abc.net.au/news/olympics/1999/06/item19990601114608_1.htm">
+# Qld says no to daylight savings for Olympics
+# </a> (1999-06-01), which quotes Queensland Premier Peter Beattie as saying
+# ``Look you've got to remember in my family when this came up last time
+# I voted for it, my wife voted against it and she said to me it's all very
+# well for you, you don't have to worry about getting the children out of
+# bed, getting them to school, getting them to sleep at night.
+# I've been through all this argument domestically...my wife rules.''
+#
+# Broken Hill will stick with South Australian time in 2000.  See:
+# <a href="http://abc.net.au/news/regionals/brokenh/monthly/regbrok-21jul1999-6.htm">
+# Broken Hill to be behind the times
+# </a> (1999-07-21).
 
-# From Arthur David Olson (1992-03-08):
-# Sources differ on whether DST ended March 6 or March 20 in 1988;
-# March 20 (the "confirmed" date) is in the chosen rules.
+# IATA SSIM (1998-09) says that the spring 2000 change for Australian
+# Capital Territory, New South Wales except Lord Howe Island and Broken
+# Hill, and Victoria will be August 27, presumably due to the Sydney Olympics.
 
-# From Bradley White (1995-05-20):
-# Prem Bob Carr announced NSW will fall into line with other E states
-# and SA and continue daylight savings to the last Sun in Mar.
+# From Eric Ulevik, referring to Sydney's Sun Herald (2000-08-13), page 29:
+# The Queensland Premier Peter Beattie is encouraging northern NSW
+# towns to use Queensland time.
 
 # Yancowinna
 
-# From John Basser (1989-01-04):
+# From John Mackin (1989-01-04):
 # `Broken Hill' means the County of Yancowinna.
 
 # From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
 # # YANCOWINNA..  [ Confirmation courtesy of Broken Hill Postmaster ]
 # #					[ Dec 1990 ]
 # ...
-# # Yancowinna uses Central Standard Time, despite it's location on the
+# # Yancowinna uses Central Standard Time, despite [its] location on the
 # # New South Wales side of the S.A. border. Most business and social dealings
 # # are with CST zones, therefore CST is legislated by local government
 # # although the switch to Summer Time occurs in line with N.S.W. There have
@@ -784,16 +862,31 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 # Lord Howe Island is located off the New South Wales coast, and is half an
 # hour ahead of NSW time.
 
-# From Paul Eggert (1995-12-19):
-# For Lord Howe we use Shanks through its time of publication (1991).
-# Lord Howe is part of NSW, so we'll guess it has used the same transition
-# times as NSW since 1991, even though Shanks writes that Lord Howe went
-# with Victoria when NSW and Victoria disagreed in 1982.
+# From James Lonergan, Secretary, Lord Howe Island Board (2000-01-27):
+# Lord Howe Island summer time in 2000/2001 will commence on the same
+# date as the rest of NSW (i.e. 2000-08-27).  For your information the
+# Lord Howe Island Board (controlling authority for the Island) is
+# seeking the community's views on various options for summer time
+# arrangements on the Island, e.g. advance clocks by 1 full hour
+# instead of only 30 minutes.  Dependent on the wishes of residents
+# the Board may approach the NSW government to change the existing
+# arrangements.  The starting date for summer time on the Island will
+# however always coincide with the rest of NSW.
+
+# From James Lonergan, Secretary, Lord Howe Island Board (2000-10-25):
+# Lord Howe Island advances clocks by 30 minutes during DST in NSW and retards
+# clocks by 30 minutes when DST finishes. Since DST was most recently
+# introduced in NSW, the "changeover" time on the Island has been 02:00 as
+# shown on clocks on LHI. I guess this means that for 30 minutes at the start
+# of DST, LHI is actually 1 hour ahead of the rest of NSW.
+
+# From Paul Eggert (2001-02-09):
+# For Lord Howe dates we use Shanks through 1989, and Lonergan thereafter.
+# For times we use Lonergan.
 
 ###############################################################################
 
-# New Zealand, from Elz' asia 1.1
-# Elz says "no guarantees"
+# New Zealand
 
 # From Mark Davies (1990-10-03):
 # the 1989/90 year was a trial of an extended "daylight saving" period.
@@ -826,24 +919,44 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 # time on both the first Sunday in October and the third Sunday in March.
 # As with Australia, we'll assume the tradition is 2:00s, not 2:00.
 #
-# From Paul Eggert (1996-11-22):
-# Shanks gives no data for Chatham; usno1989 says it's +12:45,
-# usno1995 says it's +12:45/+13:45, and IATA SSIM (1991/1996)
+# From Paul Eggert (1999-10-29):
+# Shanks gives no time data for Chatham; usno1989 says it's +12:45,
+# usno1995 says it's +12:45/+13:45, and IATA SSIM (1991/1999)
 # gives the NZ rules but with transitions at 2:45 local standard time.
-# Guess that they adopted DST in 1990.
+# Guess that they have been in lock-step with NZ since 1990.
 
 ###############################################################################
 
+
 # Fiji
 
-# Howse writes (p 162) that in 1879 the British governor of Fiji
-# enacted an ordinance standardizing the islands on +12:00.
-# Perhaps it didn't take.  We go with Shanks's more precise date in 1915.
+# Howse writes (p 153) that in 1879 the British governor of Fiji
+# enacted an ordinance standardizing the islands on Antipodean Time
+# instead of the American system (which was one day behind).
+
+# From Rives McDow (1998-10-08):
+# Fiji will introduce DST effective 0200 local time, 1998-11-01
+# until 0300 local time 1999-02-28.  Each year the DST period will
+# be from the first Sunday in November until the last Sunday in February.
+
+# From Paul Eggert (2000-01-08):
+# IATA SSIM (1999-09) says DST ends 0100 local time.  Go with McDow.
+
+# From the BBC World Service (1998-10-31 11:32 UTC):
+# The Fijiian government says the main reasons for the time change is to
+# improve productivity and reduce road accidents.  But correspondents say it
+# also hopes the move will boost Fiji's ability to compete with other pacific
+# islands in the effort to attract tourists to witness the dawning of the new
+# millenium.
+
+# http://www.fiji.gov.fj/press/2000_09/2000_09_13-05.shtml (2000-09-13)
+# reports that Fiji has discontinued DST.
 
 # Johnston
 
 # Johnston data is from usno1995.
 
+
 # Kiribati
 
 # From Paul Eggert (1996-01-22):
@@ -851,6 +964,7 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 # ``declared it the same day throught the country as of Jan. 1, 1995''
 # as part of the competition to be first into the 21st century.
 
+
 # Kwajalein
 
 # In comp.risks 14.87 (26 August 1993), Peter Neumann writes:
@@ -859,12 +973,20 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 # respect to the International Date Line, to rejoin its fellow islands,
 # going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink.
 
+
 # N Mariana Is, Guam
 
-# Howse writes (p 162) ``The Spaniards, on the other hand, reached the
+# Howse writes (p 153) ``The Spaniards, on the other hand, reached the
 # Philippines and the Ladrones from America,'' and implies that the Ladrones
 # (now called the Marianas) kept American date for quite some time.
-# Ignore this for now, as we have no hard data.  See also Asia/Manila.
+# For now, we assume the Ladrones switched at the same time as the Philippines;
+# see Asia/Manila.
+
+# US Public Law 106-564 (2000-12-23) made UTC+10 the official standard time,
+# under the name "Chamorro Standard Time".  There is no official abbreviation,
+# but Congressman Robert A. Underwood, author of the bill that became law,
+# wrote in a press release (2000-12-27) that he will seek the use of "ChST".
+
 
 # Micronesia
 
@@ -872,19 +994,155 @@ Zone	Pacific/Wallis	12:15:20 -	LMT	1901
 # ``I am certain, having lived there for the past decade, that "Truk"
 # (now properly known as Chuuk) ... is in the time zone GMT+10.''
 #
-# Shanks writes that Truk switched from GMT+10 to GMT+11 on 1978-10-01;
+# Shanks writes that Truk switched from UTC+10 to UTC+11 on 1978-10-01;
 # ignore this for now.
 
+# From Paul Eggert (1999-10-29):
+# The Federated States of Micronesia Visitors Board writes in
+# <a href="http://www.fsmgov.org/info/clocks.html">
+# The Federated States of Micronesia - Visitor Information
+# </a> (1999-01-26)
+# that Truk and Yap are UTC+10, and Ponape and Kosrae are UTC+11.
+# We don't know when Kosrae switched from UTC+12; assume January 1 for now.
+
+
+# Pitcairn
+
+# From Rives McDow (1999-11-08):
+# A Proclamation was signed by the Governor of Pitcairn on the 27th March 1998
+# with regard to Pitcairn Standard Time.  The Proclamation is as follows.
+#
+#	The local time for general purposes in the Islands shall be
+#	Co-ordinated Universal time minus 8 hours and shall be known
+#	as Pitcairn Standard Time.
+#
+# ... I have also seen Pitcairn listed as UTC minus 9 hours in several
+# references, and can only assume that this was an error in interpretation
+# somehow in light of this proclamation.
+
+# From Rives McDow (1999-11-09):
+# The Proclamation regarding Pitcairn time came into effect on 27 April 1998
+# ... at midnight.
+
+# From Howie Phelps (1999-11-10), who talked to a Pitcairner via shortwave:
+# Betty Christian told me yesterday that their local time is the same as
+# Pacific Standard Time. They used to be 1/2 hour different from us here in
+# Sacramento but it was changed a couple of years ago.
+
+
 # Samoa
 
-# Howse writes that in 1879 the King of Samoa decided to change
+# Howse writes (p 153, citing p 10 of the 1883-11-18 New York Herald)
+# that in 1879 the King of Samoa decided to change
 # ``the date in his kingdom from the Antipodean to the American system,
 # ordaining -- by a masterpiece of diplomatic flattery -- that
 # the Fourth of July should be celebrated twice in that year.''
 
+
 # Tonga
 
 # From Paul Eggert (1996-01-22):
 # Today's _Wall Street Journal_ (p 1) reports that ``Tonga has been plotting
 # to sneak ahead of [New Zealanders] by introducing daylight-saving time.''
 # Since Kiribati has moved the Date Line it's not clear what Tonga will do.
+
+# Don Mundell writes in the 1997-02-20 Tonga Chronicle
+# <a href="http://www.tongatapu.net.to/tonga/homeland/timebegins.htm">
+# How Tonga became `The Land where Time Begins'
+# </a>:
+
+# Until 1941 Tonga maintained a standard time 50 minutes ahead of NZST
+# 12 hours and 20 minutes ahead of GMT.  When New Zealand adjusted its
+# standard time in 1940s, Tonga had the choice of subtracting from its
+# local time to come on the same standard time as New Zealand or of
+# advancing its time to maintain the differential of 13 degrees
+# (approximately 50 minutes ahead of New Zealand time).
+#
+# Because His Majesty King Taufa'ahau Tupou IV, then Crown Prince
+# Tungi, preferred to ensure Tonga's title as the land where time
+# begins, the Legislative Assembly approved the latter change.
+#
+# But some of the older, more conservative members from the outer
+# islands objected. "If at midnight on Dec. 31, we move ahead 40
+# minutes, as your Royal Highness wishes, what becomes of the 40
+# minutes we have lost?"
+#
+# The Crown Prince, presented an unanswerable argument: "Remember that
+# on the World Day of Prayer, you would be the first people on Earth
+# to say your prayers in the morning."
+
+# From Paul Eggert (1999-08-12):
+# Shanks says the transition was on 1968-10-01; go with Mundell.
+
+# From Eric Ulevik (1999-05-03):
+# Tonga's director of tourism, who is also secretary of the National Millenium
+# Committee, has a plan to get Tonga back in front.
+# He has proposed a one-off move to tropical daylight saving for Tonga from
+# October to March, which has won approval in principle from the Tongan
+# Government.
+
+# From Steffen Thorsen [straen@thorsen.priv.no] (1999-09-09):
+# * Tonga will introduce DST in November
+#
+# I was given this link by John Letts <johnletts@earthlink.net>:
+# <a hef="http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm">
+# http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm
+# </a>
+#
+# I have not been able to find exact dates for the transition in November
+# yet. By reading this article it seems like Fiji will be 14 hours ahead
+# of UTC as well, but as far as I know Fiji will only be 13 hours ahead
+# (12 + 1 hour DST).
+
+# From Arthur David Olson [arthur_david_olson@nih.gov] (1999-09-20):
+# According to <a href="http://www.tongaonline.com/news/sept1799.html>
+# http://www.tongaonline.com/news/sept1799.html
+# </a>:
+# "Daylight Savings Time will take effect on Oct. 2 through April 15, 2000
+# and annually thereafter from the first Saturday in October through the
+# third Saturday of April.  Under the system approved by Privy Council on
+# Sept. 10, clocks must be turned ahead one hour on the opening day and
+# set back an hour on the closing date."
+# Alas, no indication of the time of day.
+
+# From Rives McDow (1999-10-06):
+# Tonga started its Daylight Saving on Saturday morning October 2nd at 0200am.
+# Daylight Saving ends on April 16 at 0300am which is Sunday morning.
+
+# From Steffen Thorsen (2000-10-31):
+# Back in March I found a notice on the website http://www.tongaonline.com
+# that Tonga changed back to standard time one month early, on March 19
+# instead of the original reported date April 16. Unfortunately, the article
+# is no longer available on the site, and I did not make a copy of the
+# text, and I have forgotten to report it here.
+# (Original URL was: http://www.tongaonline.com/news/march162000.htm )
+
+# From Rives McDow (2000-12-01):
+# Tonga is observing DST as of 2000-11-04 and will stop on 2001-01-27.
+
+###############################################################################
+
+# The International Date Line
+
+# From Gwillim Law (2000-01-03):
+#
+# The International Date Line is not defined by any international standard,
+# convention, or treaty.  Mapmakers are free to draw it as they please.
+# Reputable mapmakers will simply ensure that every point of land appears on
+# the correct side of the IDL, according to the date legally observed there.
+#
+# When Kiribati adopted a uniform date in 1995, thereby moving the Phoenix and
+# Line Islands to the west side of the IDL (or, if you prefer, moving the IDL
+# to the east side of the Phoenix and Line Islands), I suppose that most
+# mapmakers redrew the IDL following the boundary of Kiribati.  Even that line
+# has a rather arbitrary nature.  The straight-line boundaries between Pacific
+# island nations that are shown on many maps are based on an international
+# convention, but are not legally binding national borders.
+#
+# An Anglo-French Conference on Time-Keeping at Sea (June, 1917) agreed that
+# legal time on the high seas would be zone time, i.e., the standard time at
+# the nearest meridian that is a multiple of fifteen degrees.  The date is
+# governed by the IDL; therefore, even on the high seas, there may be some
+# places as late as fourteen hours later than UTC.  And, since the IDL is not
+# an international standard, there are some places on the high seas where the
+# correct date is ambiguous.
diff --git a/zic.tproj/datfiles/backward b/zic.tproj/datfiles/backward
index 793d37b..0bfa872 100644
--- a/zic.tproj/datfiles/backward
+++ b/zic.tproj/datfiles/backward
@@ -1,14 +1,19 @@
-#	$OpenBSD: backward,v 1.4 1997/01/14 04:36:50 millert Exp $
-# @(#)backward	7.13
+# @(#)backward	7.20
 
 # This file provides links between current names for time zones
 # and their old names.  Many names changed in late 1993.
 
 Link	America/Adak		America/Atka
+Link	America/Tijuana		America/Ensenada
 Link	America/Indianapolis	America/Fort_Wayne
 Link	America/Indiana/Knox	America/Knox_IN
+Link	America/Rio_Branco	America/Porto_Acre
 Link	America/St_Thomas	America/Virgin
+Link	Asia/Dhaka		Asia/Dacca
+Link	Asia/Ashgabat		Asia/Ashkhabad
 Link	Asia/Jerusalem		Asia/Tel_Aviv
+Link	Asia/Thimphu		Asia/Thimbu
+Link	Asia/Ulaanbaatar	Asia/Ulan_Bator
 Link	Australia/Sydney	Australia/ACT
 Link	Australia/Sydney	Australia/Canberra
 Link	Australia/Lord_Howe	Australia/LHI
@@ -39,7 +44,8 @@ Link	America/Havana		Cuba
 Link	Africa/Cairo		Egypt
 Link	Europe/Dublin		Eire
 Link	Europe/London		GB
-Link	Etc/GMT			GMT
+Link	Europe/London		GB-Eire
+Link	Europe/Chisinau		Europe/Tiraspol
 Link	Etc/GMT+0		GMT+0
 Link	Etc/GMT-0		GMT-0
 Link	Etc/GMT0		GMT0
diff --git a/zic.tproj/datfiles/etcetera b/zic.tproj/datfiles/etcetera
index 8786abe..f87a76e 100644
--- a/zic.tproj/datfiles/etcetera
+++ b/zic.tproj/datfiles/etcetera
@@ -1,5 +1,4 @@
-#	$OpenBSD: etcetera,v 1.3 1997/01/14 04:36:51 millert Exp $
-# @(#)etcetera	7.6
+# @(#)etcetera	7.11
 
 # These entries are mostly present for historical reasons, so that
 # people in areas not otherwise covered by the tz files could "zic -l"
@@ -11,6 +10,12 @@ Zone	Etc/GMT		0	-	GMT
 Zone	Etc/UTC		0	-	UTC
 Zone	Etc/UCT		0	-	UCT
 
+# The following link uses older naming conventions,
+# but it belongs here, not in the file `backward',
+# as functions like gmtime load the "GMT" file to handle leap seconds properly.
+# We want this to work even on installations that omit the other older names.
+Link	Etc/GMT				GMT
+
 Link	Etc/UTC				Etc/Universal
 Link	Etc/UTC				Etc/Zulu
 
@@ -19,10 +24,24 @@ Link	Etc/GMT				Etc/GMT-0
 Link	Etc/GMT				Etc/GMT+0
 Link	Etc/GMT				Etc/GMT0
 
-# We use POSIX-style signedness in the names and output,
-# internal-style signedness in the specifications.
-# For example, TZ=Etc/GMT+4 corresponds to 4 hours _behind_ GMT;
-# it is equivalent to TZ=GMT+4, which is implemented directly as per POSIX.
+# We use POSIX-style signs in the Zone names and the output abbreviations,
+# even though this is the opposite of what many people expect.
+# POSIX has positive signs west of Greenwich, but many people expect
+# positive signs east of Greenwich.  For example, TZ='Etc/GMT+4' uses
+# the abbreviation "GMT+4" and corresponds to 4 hours behind UTC
+# (i.e. west of Greenwich) even though many people would expect it to
+# mean 4 hours ahead of UTC (i.e. east of Greenwich).
+#
+# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation
+# (which is not yet supported by the tz code) allows for
+# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
+# ISO 8601 you can use TZ='<-0400>+4'.  Thus the commonly-expected
+# offset is kept within the angle bracket (and is used for display)
+# while the POSIX sign is kept outside the angle bracket (and is used
+# for calculation).
+#
+# Do not use a TZ setting like TZ='GMT+4', which is four hours behind
+# GMT but uses the completely misleading abbreviation "GMT".
 
 # Earlier incarnations of this package were not POSIX-compliant,
 # and had lines such as
diff --git a/zic.tproj/datfiles/europe b/zic.tproj/datfiles/europe
index ac1aec1..04a8f84 100644
--- a/zic.tproj/datfiles/europe
+++ b/zic.tproj/datfiles/europe
@@ -1,27 +1,36 @@
-#	$OpenBSD: europe,v 1.5 1997/01/14 04:36:52 millert Exp $
-# @(#)europe	7.42
+# @(#)europe	7.78
+
+# $FreeBSD: src/share/zoneinfo/europe,v 1.22 2001/04/06 16:46:52 wollman Exp $
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
 # tz@elsie.nci.nih.gov for general use in the future).
 
-# From Paul Eggert <eggert@twinsun.com> (1996-11-22):
+# From Paul Eggert <eggert@twinsun.com> (1999-10-29):
 # A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
+# Thomas G. Shanks, The International Atlas (5th edition),
+# San Diego: ACS Publications, Inc. (1999).
 #
-# Gwillim Law <LAW@encmail.encompass.com> writes that a good source
+# Gwillim Law <Gwil_Law@bridge-point.com> writes that a good source
 # for recent time zone data is the International Air Transport
 # Association's Standard Schedules Information Manual (IATA SSIM),
 # published semiannually.  Law sent in several helpful summaries
 # of the IATA's data after 1990.
 #
-# Except where otherwise noted, Shanks is the source for entries through 1990,
-# and IATA SSIM is the source for entries after 1990.
+# Except where otherwise noted, Shanks is the source for entries through 1991,
+# and IATA SSIM is the source for entries afterwards.
+#
+# Other sources occasionally used include:
 #
-# Another source occasionally used is Edward W. Whitman, World Time Differences,
-# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
-# I found in the UCLA library.
+#	Edward W. Whitman, World Time Differences,
+#	Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
+#	which I found in the UCLA library.
+#
+#	Brazil's Departamento Servico da Hora (DSH),
+#	<a href="http://pcdsh01.on.br/HISTHV.htm">
+#	History of Summer Time
+#	</a> (1998-09-21, in Portuguese)
+
 #
 # I invented the abbreviations marked `*' in the following table;
 # the rest are from earlier versions of this file, or from other sources.
@@ -38,11 +47,8 @@
 #	 2:00	EET EEST Eastern Europe
 #	 3:00	MSK MSD	Moscow
 #
-# See the `africa' file for time zone naming and abbreviation conventions.
-#
 # A reliable and entertaining source about time zones, especially in Britain,
-# is Derek Howse, Greenwich time and the discovery of the longitude,
-# Oxford University Press (1980).
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 
 # From Peter Ilieve <peter@memex.co.uk> (1994-12-04),
 # The original six [EU members]: Belgium, France, (West) Germany, Italy,
@@ -68,8 +74,7 @@
 
 ###############################################################################
 
-# United Kingdom
-# The UK and its colonies adopted the Gregorian calendar on 1752-09-14.
+# Britain (United Kingdom) and Ireland (Eire)
 
 # From Peter Ilieve <peter@memex.co.uk> (1994-07-06):
 #
@@ -97,35 +102,44 @@
 # Howse writes that Britain was the first country to use standard time.
 # The railways cared most about the inconsistencies of local mean time,
 # and it was they who forced a uniform time on the country.
-# The original idea was credited to Dr. William Hyde Wollaston (1766-1828);
-# it was popularized in 1840 by Capt. Basil Hall, RN (1788-1844),
-# famed explorer and former Commissioner for Longitude.
+# The original idea was credited to Dr. William Hyde Wollaston (1766-1828)
+# and was popularized by Abraham Follett Osler (1808-1903).
 # The first railway to adopt London time was the Great Western Railway
 # in November 1840; other railways followed suit, and by 1847 most
-# (though not all) railways used London time.  On 1847 Sep 22 the
+# (though not all) railways used London time.  On 1847-09-22 the
 # Railway Clearing House, an industry standards body, recommended that GMT be
-# adopted at all stations; the January 1848 Bradshaw's lists most major
+# adopted at all stations as soon as the General Post Office permitted it.
+# The transition occurred on 12-01 for the L&NW, the Caledonian,
+# and presumably other railways; the January 1848 Bradshaw's lists many
 # railways as using GMT.  By 1855 the vast majority of public
-# clocks in Britain were set to GMT (though some, like the Great Clock
-# in Tom Tower at Christ Church, Oxford, were fitted with two minute hands,
+# clocks in Britain were set to GMT (though some, like the great clock
+# on Tom Tower at Christ Church, Oxford, were fitted with two minute hands,
 # one for local time and one for GMT).  The last major holdout was the legal
 # system, which stubbornly stuck to local time for many years, leading
 # to oddities like polls opening at 08:13 and closing at 16:13.
 # The legal system finally switched to GMT when the Statutes (Definition
-# of Time) Act took effect; it received the Royal Assent on 1880 Aug 2.
+# of Time) Act took effect; it received the Royal Assent on 1880-08-02.
 #
 # In the tables below, we condense this complicated story into a single
-# transition date for London, namely 1847 Sep 22.  We don't know as much
-# about Dublin, so we use 1880 Aug 2, the legal transition time.
+# transition date for London, namely 1847-12-01.  We don't know as much
+# about Dublin, so we use 1880-08-02, the legal transition time.
 
-# From Paul Eggert (1996-06-12):
+# From Paul Eggert (1999-01-30):
 # Summer Time was first seriously proposed by William Willett (1857-1915),
-# a London builder who circulated a pamphlet ``Waste of Daylight'' (1907)
+# a London builder and member of the Royal Astronomical Society
+# who circulated a pamphlet ``The Waste of Daylight'' (1907)
 # that proposed advancing clocks 20 minutes on each of four Sundays in April,
 # and retarding them by the same amount on four Sundays in September.
 # A bill was drafted in 1909 and introduced in Parliament several times,
 # but it met with ridicule and opposition, especially from farming interests.
 # One-hour Summer Time was eventually adopted as a wartime measure in 1916.
+# See:
+# <a href="http://www.the-times.co.uk/news/pages/tim/2000/05/18/x-timcrtcrt01011.html">
+# Summer Time Arrives Early, The Times (2000-05-18)
+# </a>
+# A monument was erected in 1927 to Willett, in an open space in a 45-acre wood
+# near Chiselhurst, Kent that was purchased by popular subscription and open
+# to the public.
 
 # From Paul Eggert (1996-09-03):
 # The OED Supplement says that the English originally said ``Daylight Saving''
@@ -144,543 +158,96 @@
 # If you can predict what Parliament will do, you should be in
 # politics making a fortune, not computing.
 
-# From Peter Ilieve <peter@memex.co.uk> (1993-09-03):
-#
-# Our Government...couldn't...make a decision after the 1989 consultation
-# exercise about the UK changing its timezone so it just let things drift
-# (different from deciding to keep the status quo).  According to the
-# Summer Time Order 1992 (SI 1992/1729) the dates of Summer Time for 1993
-# and 1994 are:
-#	Start		End
-# 1993	28 March	24 October
-# 1994	27 March	23 October
-# All start and end times are at 01:00 GMT.
-#
-# There [was] an error in your tables for the start and end times prior to 1981.
-# The UK always used to change at 02:00 GMT. In 1981 it changed to 01:00 GMT
-# as a part of EC harmonisation and has remained at that time since.
-#
-# I have found the default algorithm for UK Summer Time, it is in the
-# Summer Time Act 1972. Section 1 states that in the absence of an Order
-# in Council Summer Time starts at 02:00 GMT on the morning of the day
-# after the third Saturday in March, unless that day is Easter Day, in
-# which case it is the morning of the day after the second Saturday.
-# It ends at 02:00 GMT on the morning of the day after the fourth Saturday
-# in October. (All the redundant `morning of the day ...' is in the Act.)
-# This is only of passing interest now as it will always be overridden by
-# an Order in Council (a Statutory Instrument, the SI thing mentioned above)
-# to specify the EC specified dates.
-
-# From Peter Ilieve <peter@memex.co.uk> (1993-10-18):
-#
-# My contact in the Ministry of Defence Public Relations department
-# accepted the challenge of looking into this and produced the following,
-# from Hansard (the official record of the UK Parliament), Oral Answers,
-# 1 March 1945, cols 1559--60:
-#
-# `58. Major Sir Goronwy Owen asked the Secretary of State for the Home
-# Department if he is now able to state the Government's proposals
-# regarding double summer time.
-#
-# [two other similar questions omitted]
-#
-# Mr. H. Morrison: The Government, in reviewing the matter, have
-# considered, [...] the conclusion has been reached that the adoption of
-# double summer time from the beginning of April is essential to the
-# maintenance of the war effort. [...] As 1st April is Easter Sunday,
-# when very early services are held in many churches, it is proposed that
-# double summer time shall start not in the night preceding Easter
-# Sunday, but in the night of Sunday- Monday so that it will operate from
-# Monday, 2nd April.'
-
 # From Chris Carrier <72157.3334@CompuServe.COM> (1996-06-14):
 # I remember reading in various wartime issues of the London Times the
 # acronym BDST for British Double Summer Time.  Look for the published
 # time of sunrise and sunset in The Times, when BDST was in effect, and
 # if you find a zone reference it will say, "All times B.D.S.T."
 
-# From Peter Ilieve <peter@memex.co.uk> (1993-09-03):
-#
-# > # Current rules
-# > Rule GB-Eire 1981	max	-	Mar	lastSun	1:00s	1:00	BST
-# > Rule GB-Eire 1981	max	-	Oct	Sun>=23	1:00s	0	GMT
-#
-# The ending rule here doesn't match the EC rules, which specify the fourth
-# Sunday in October for the UK and Eire. The `fourth Sunday' rule wasn't
-# followed in 1989, but then the sixth EC directive wasn't in force then
-# and I don't know what previous ones said. 1995 is the next year with
-# the 4th Sun on 22 Oct, but that year isn't covered by the UK Summer Time
-# Order or the sixth EC directive. Your Oct Sun>=23 rule matches history
-# and with things only announced for 2 years or so in advance who knows
-# what will happen.
-#
-# There are renewed rumours that the Government here will make another
-# attempt at resolving this issue, which is what prompted me to start
-# asking the Home Office and the EC about it again. The EC categorically
-# state they are not asking anybody to change timezone, they only want
-# common start/end dates. The UK Govt. seem to want to change our zone
-# and blame the resulting fuss on the EC. Me, I think we should scrap
-# summer time completely, noon is when the Sun is overhead, and that should
-# be the end of it.
-
-# From Peter Ilieve <peter@memex.co.uk> (1993-10-22):
-#
-# I now have the text of the Summer Time Act 1916, the granddaddy of them all.
-# It is headed: `An Act to provide for the Time in Great Britain and Ireland
-# being in advance of Greenwich and Dublin mean time respectively in the
-# summer months'.
-#
-# It specifies 21 May and 1 October for 1916 (both at 02:00 GMT) and whatever
-# dates an Order in Council may specify for subsequent years.
-#
-# Section 4 states: `This act shall apply to Ireland in like manner as it
-# applies to Great Britain, with the substitution however of references
-# to Dublin mean time for references to Greenwich mean time.'
-#
-# Lorna, my learned legal friend who supplied it, also offers this quote
-# from Halsbury's Statutes on the extent of Acts:
-#
-# `An Act of the United Kingdom Parliament is to be construed prima facie
-# to apply to the whole of the United Kingdom and not to any place outside.
-# [...] The expression "United Kingdom" for this purpose includes (since
-# 1922) Great Britain (ie. England, Wales and Scotland) and Northern Ireland,
-# but it does not include the Channel Islands or the Isle of Man.'
-#
-# She goes on to say the seminal event of 1922 was the establishment of
-# the Irish Free State, now called Eire.
-#
-# The Act doesn't say anything about Wales (or Scotland) so I would assert
-# that Shanks is wrong here. I would like to know why he thinks Wales
-# was different.
-#
-# It also confirms the fact that Ireland followed Dublin time back then,
-# and 25 minutes behind Greenwich, as Shanks has it, would be correct.
-
-# From Peter Ilieve <peter@memex.co.uk> (1993-10-28):
-#
-# I now have before me, thanks to my learned legal friend Lorna, the text of
-# the Time (Ireland) Act 1916.
-#
-# It says that as from 2 AM Dublin Mean Time on 1 October 1916 the time
-# for general purposes in Ireland shall be the same as the rest of Great
-# Britain (ie. GMT with the Summer Time periods specified by the Summer Time
-# Act 1916)....  As Ireland was behind GMT/BST at 02:00 DMT on 1 Oct GB would
-# have already put the clocks back. Using DST as Dublin Summer Time the
-# sequence would have been:
-# Dublin		London
-# 02:34 DST	02:59 BST
-# 02:35 DST	02:00 GMT
-# 02:59 DST	02:24 GMT
-# 02:25 GMT	02:25 GMT
-# with the transition 03:00 DST -> 02:00 DMT -> 02:25 GMT all at once.
-#
-# In a table of repeals in the Schedule to the Act it mentions the
-# Statutes (Definition of Time) Act 1880. This is presumably the source
-# of the 1880 date in Shanks.  The little bit of it that is repealed
-# also refers solely to Ireland and Dublin Mean Time.
-
-# From Peter Ilieve <peter@memex.co.uk> (1993-10-29):
-#
-# My case is that, with the sole exception of Ireland in 1916 using Dublin
-# Mean Time, Summer Time has been uniform throughout the United Kingdom
-# ever since it first started in 1916.
-#
-# The United Kingdom is England, Wales and Scotland plus all of Ireland from
-# 1916 up to and including 1921, or plus Northern Ireland from 1922 to date.
-#
-# The dates used are those specified in the table in Summer Time: A Consultation
-# Document (Cm 722, 1989) that are now included in the europe file, with a
-# change to a single date, the start in 1924. I made a typo in my 1989 mail
-# and the table itself is also wrong.  The correct date is 13 April.
-# The times were 02:00 GMT up to and including 1980, 01:00 GMT from 1981 on,
-# except for wartime double summer time.
-#
-# As evidence I would cite:
-#
-# - The Summer Time Act, 1916.
-#
-# This specifically states that it applies to Ireland, specifies dates of
-# 21 May and 1 October and times of 02:00, and says that in Ireland the
-# times relate to Dublin mean time. It specifies an offset of 1 hour.
-#
-# - The Time (Ireland) Act, 1916
-#
-# This abolishes Dublin mean time on 02:00 DMT 1 October 1916.
-# It repeals that section of the Statutes (Definition of Time) Act, 1880
-# that specifies DMT. It is therefore a safe bet that DMT existed at least
-# from 1880 and was the only alternative standard time in the UK.
-#
-# - The Summer Time Act, 1922
-#
-# This specifies an offset of 1 hour and dates of the day after the third
-# Saturday in April, unless that be Easter, in which case it is the day after
-# the second Saturday, and the day after the third Saturday in September.
-# The time is 02:00 GMT. It applied in 1922 and 1923, and longer if Parliament
-# so approved.
-#
-# It specifically states that it applies to Northern Ireland, the Channel
-# Islands, and the Isle of Man.
-#
-# - The Summer Time Act, 1925
-#
-# This makes the 1922 Act permanent, with a change to the end date to the
-# day after the first Saturday in October. It says nothing about extent,
-# so that part of the 1922 Act will still apply.
-#
-# - The Defence (Summer Time) Regulations, 1939, SR&O 1939 No. 1379
-#   [SR&O == Statutory Regulation and Order]
-#
-# These were made under the Emergency Powers (Defence) Act, 1939.
-# It changes the end date to be the day after the third Saturday in November.
-# It makes consequential changes to some vehicle lighting legislation,
-# which includes the Motor Vehicles and Road Traffic (Northern Ireland) Act,
-# 1934, so it seems clear it applies in Northern Ireland.
-#
-# - An Order in Council amending the The Defence (Summer Time) Regulations,
-#   1939, SR&O 1940 No. 1883
-#
-# This continues summer time throughout the year after it starts in 1940.
-# It says nothing about extent and has no consequential changes.
-#
-# - An Order in Council amending the The Defence (Summer Time) Regulations,
-#   1939, SR&O 1941 No. 476
-#
-# This introduces double summer time, starting at 01:00 GMT on the day after
-# the first Saturday in May and ending at 01:00 GMT on the day after the
-# second Saturday in August, offset another hour from normal summer time,
-# which continues throughout the rest of the year. It goes on a lot about
-# consequential changes to agricultural wages legislation, and says in part
-# `... and in its application to Northern Ireland have effect as
-# if for the references to the Agricultural Wages (Regulation) Acts, 1924 and
-# 1940, there were substituted references to the Agricultural Wages (Regulation)
-# Acts (Northern Ireland), 1939 and 1940, ...'. It also has a similar section
-# for Scotland. Both sections substitute the local Agricultural Wages Board
-# for the Agricultural Wages Board for England and Wales, showing that
-# England and Wales were indivisible.
-#
-# - An Order in Council amending the The Defence (Summer Time) Regulations,
-#   1939, SR&O 1942 No. 506
-#
-# This changes the start date of double summer time to the day after the first
-# Saturday in April. It says nothing about extent.
-#
-# - An Order in Council amending the The Defence (Summer Time) Regulations,
-#   1939, SR&O 1944 No. 932
-#
-# This changed the end date of double summer time to 17 September 1944.
-# (I don't have the text of this, just a note of what it did, the text almost
-# certainly had the `day after the nth Saturday' form.)
-#
-# (I am missing whatever regulations there were to change things in 1945
-# and the Summer Time Act, 1947.)
-#
-# - The British Standard Time Act, 1968
-#
-# This came into force on 27 October 1968 and continued summer time throughout
-# the year as an experiment until it expired on 31 October 1971.
-# There was no double summer time so we didn't have to change the clocks at all.
-# It specifically said it applied to Northern Ireland. It also said it
-# applied to Jersey, Guernsey and the Isle of Man unless they passed
-# measures saying it didn't.
-#
-# - The Manx Time Act, 1968
-#
-# This is an Act of Tynwald (the Isle of Man Parliament) that said that
-# henceforth Manx time would be the same as the time in Great Britain.
-#
-# - The Summer Time Act, 1972
-#
-# This specified a reversion to normal summer time behaviour with a start
-# date of the day after the third Saturday in March, unless that is Easter,
-# when it is the day after the second Saturday, and an end date of the day
-# after the fourth Saturday in October. Times are at 02:00 GMT, offset is
-# 1 hour.
-#
-# It has the same wording about extent as the British Standard Time Act, 1968,
-# applying to Northern Ireland unconditionally and to Jersey, Guernsey and the
-# Isle of Man if they don't do something about it.
-#
-# (I am missing various Summer Time Orders that modified the 1972 Act to
-# harmonise with the EC since 1981. The major change is that the time changes
-# to 01:00 GMT.)
-#
-# - The Summer Time Order, 1992, SI 1992/1729 [SI == Statutory Instrument]
-#
-# This specifies dates of:
-#       Start       End
-# 1993  28 March    24 October
-# 1994  27 March    23 October
-# All start and end times are at 01:00 GMT....
-#
-# - Some text on the extent of Acts, from Halsbury's Statutes
-#
-# `An Act of the United Kingdom Parliament is to be construed prima facie
-# to apply to the whole of the United Kingdom and not to any place outside.
-# [...] The expression "United Kingdom" for this purpose includes (since
-# 1922) Great Britain (ie. England, Wales and Scotland) and Northern Ireland,
-# but it does not include the Channel Islands or the Isle of Man.'
-#
-# So, many of these measures specifically include Northern Ireland,
-# the Channel Islands and the Isle of Man. None of them exclude any
-# part of the UK. The default interpretation of Acts is that they apply
-# throughout the UK.
-#
-# With that, I rest my case Milud :-)
-#
-# Thanks are due to my learned legal friend Lorna Montgomerie, who dug out
-# the dusty old statutes, and to Melanie Allison of the Ministry of Defence,
-# who provided the wartime regulations and a snippet of Hansard explaining
-# why double summer time started on a Monday in 1945 (it was Easter).
-
-# From Peter Ilieve <peter@aldie.co.uk> (1996-05-29):
-# I have now got a copy of the British Standard Time Act 1968.
-# It says (S4(2)) that it expires at 02:00 GMT on 31 October 1971 unless
-# an Order in Council was passed in Parliament to make the Act permanent.
-# No Order was passed, so 02:00 1971-10-31 it is...
-#
-# Interestingly, it says baldly `This Act shall come into force on
-# 27 October 1968', without giving a time. As S1 of the Act merely
-# stated that `The time for general purposes in the United Kingdom
-# (to be known as British standard time) shall be one hour in
-# advance of Greenwich mean time throughout the year; ...' you could
-# possibly argue that the start time of BStandardT was 00:00 1968-10-27,
-# especially as the Act repealed the Summer Time Acts 1916--1947 in toto,
-# thereby destroying the authority of the Summer Time Order specifying
-# summer time in 1968....
-
-# From Peter Ilieve <peter@memex.co.uk> (1993-11-18)
-#
-# Here is a revised version of my tabrules file for the perl script I sent
-# before. I have personally verified the various Orders back to 1953 and
-# all the Acts.
-#
-# There are no changes to the dates we already have.
-#
-# My doubt about an early start in 1967 on 18 Feb was misplaced, the Order
-# does say 18 Feb. This is an interesting case as the first Order gave a
-# different date of 7 April 1967 for the Isle of Man but this was changed
-# before it came into effect by another Order for the Isle of Man alone.
-#
-# I don't think I will be able to find any more of the earlier Orders.
-# The annual volumes for 1949--52 do not contain the various Summer Time
-# Orders. They therefore don't appear in the index. They rate a mention in
-# italics in the numerical list at the start but that is all.
-# I think what happens is that the annual volume is produced well after the
-# end of the year in question, by which time the Summer Time Order is spent.
-# They assume that nobody would ever be stupid enough to want to see it
-# again so they leave it out.
-#
-# It might be a good idea to put this table, or the output of tabscript
-# showing all the moves because of Easter, in the europe file comments in
-# place of my old transcription of the Green Paper table [the UK Government
-# paper "Summer Time: A Consultation Document" (HMSO Cm722 June 1989)].
-#
-#		Peter Ilieve		peter@memex.co.uk
-#
-#
-# ## control file for tabscript, a program to generate UK summer time dates
-# ## matching the table in Cm 722, the 1989 Green Paper.
-# ## Lines like this are comments.
-# ## Lines with a single # at the start are copied into the output
-# ## Control lines are of the form
-# ## <years> <start date> <end date> <flags> <double start> <double end>
-# ## <years> is either a single year or a hyphen separated range, with --
-# ## also accepted as I use this in TeX a lot.
-# ## <start date> and <end date> are a digit followed bu a month name.
-# ## It is either an nth Saturday or an explicit date, depending on <flags>.
-# ## 0 and/or none are used when there is no date, as during 1968--71.
-# ## <flags> can contain `fixed' to indicate explicit dates and `double'
-# ## to indicate double summer time dates are present.
-# ## At present double requires fixed as well.
-# ## <double start> and <double end> are like the start and end dates, with
-# ## the exception of the 0 and/or none feature.
-#
-# ## Blank lines are also ignored.
-#
-# ## Places where I am uncertain, not having personally verified the dates
-# ## against the Act or Order, are marked ???
-# ## These dates are taken from the Cm 722 table.
-#
-# # Summer Time Act, 1916
-# 1916 21 May 1 October fixed
-#
-# ## I haven't yet looked for Orders for 1916--22 and I doubt I will find them.
-# # unknown Order or Orders ???
-# 1917 8 apr 17 sep fixed
-# 1918 24 mar 30 sep fixed
-# 1919 30 mar 29 sep fixed
-# # end date extended in 1920 from 27 Sep because of coal strike (from Cm 722)
-# 1920 28 mar 25 oct fixed
-# 1921 3 apr 3 oct fixed
-#
-# # Summer Time Act, 1922
-# # came into force 22 July 1922, too late for 1922, so missing Order ???
-# 1922 26 mar 8 oct fixed
-# 1923-1924 3 April 3 September
-#
-# # Summer Time Act, 1925
-# 1925--1938 3 April 1 October
-#
-# # Defence (Summer Time) Regulations, 1939
-# 1939 3 April 3 November
-# # 1940 amendment (SR&O 1940 Nos. 172 & 1883)
-# 1940 4 feb 0 none
-# # 1941 amendment (SR&O 1941 No. 476)
-# 1941 0 none 0 none fixed,double 4 may 10 aug
-# # 1942 amendment (SR&O 1942 No. 506)
-# 1942 0 none 0 none fixed,double 5 apr 9 aug
-# 1943 0 none 0 none fixed,double 4 apr 15 aug
-# # 1944 amendment (SR&O 1944 No. 932)
-# 1944 0 none 0 none fixed,double 2 apr 17 sep
-# # 1945 dates from Hansard, Oral Answers, 1 March 1945
-# 1945 0 none 7 oct fixed,double 2 apr 15 jul
-#
-# # reversion to Summer Time Act, 1925
-# 1946 3 April 1 October
-#
-# # Summer Time Act, 1947
-# # Fixed dates for 1947 only, gives power to have double summer time
-# 1947 16 mar 2 nov fixed,double 13 apr 10 aug
-# ## I can't find any trace of the Order for 1948.
-# # Unknown Order ???
-# 1948 14 mar 31 oct fixed
-# ## I know the numbers for the 1949--52 ones but the text is missing from the
-# ## annual volumes. I also don't know if the 49 Order was for 49 or 50, etc.
-# # Summer Time Order, 1949 (SI1949/373) ???
-# 1949 3 apr 30 oct fixed
-# # Summer Time Order, 1950 (SI1950/518) ???
-# 1950 16 apr 22 oct fixed
-# # Summer Time Order, 1951 (SI1951/430) ???
-# 1951 15 apr 21 oct fixed
-# # Summer Time Order, 1952 (SI1952/451) ???
-# 1952 20 apr 26 oct fixed
-#
-# # reversion to Summer Time Act, 1925
-# 1953--1960 3 April 1 October
-#
-# ## All Orders from here on specify fixed dates, not day after nth Sunday
-# ## Start pattern looks like Mar lastSun up to 1963, Mar Sun>=19 up to 1967.
-# ## End pattern looks like Oct Sun>=23 up to 1967.
-# # Summer Time Order, 1961 (SI1961/71)
-# 1961 26 March 29 October fixed
-# # Summer Time (1962) Order, 1961 (SI1961/2465)
-# 1962 25 Mar 28 Oct fixed
-# # Summer Time Order, 1963 (SI1963/81)
-# 1963 31 March 27 October fixed
-# # Summer Time (1964) Order, 1963 (SI1963/2101)
-# 1964 22 March 25 October fixed
-# # Summer Time Order, 1964 (SI1964/1201)
-# 1965 21 Mar 24 Oct fixed
-# 1966 20 Mar 23 Oct fixed
-# 1967 19 Mar 29 Oct fixed
-# # Summer Time Order, 1967 (SI1967/1148)
-# # Specifies different start date of 7 April for Isle of Man
-# # Summer Time Order, 1968 (SI1968/117)
-# # Changes Isle of Man start date to 18 Feb to match rest of UK
-# # British Standard Time Act, 1968
-# 1968 18 feb 0 none fixed
-# 1969--1970 0 none 0 none
-# 1971 0 none 31 oct fixed
-#
-# # Summer Time Act, 1972
-# 1972-1980 3 March 4 October
-#
-# # The pattern here looks like Last Sun in Mar, day after 4th Sat in Oct
-# # First EC Directive ???
-# # Summer Time Order, 1980 (SI1980/1089)
-# 1981    29 Mar  25 Oct fixed
-# 1982    28 Mar  24 Oct fixed
-# # Second EC Directive ???
-# # Summer Time Order, 1982 (SI1982/1673)
-# 1983    27 Mar  23 Oct fixed
-# 1984    25 Mar  28 Oct fixed
-# 1985    31 Mar  27 Oct fixed
-# # Third EC Directive ???
-# # Summer Time Order, 1986 (SI1986/223)
-# 1986    30 Mar  26 Oct fixed
-# 1987    29 Mar  25 Oct fixed
-# 1988    27 Mar  23 Oct fixed
-# # Fourth EC Directive ???
-# # Summer Time Order, 1988 (SI1988/931)
-# 1989    26 Mar  29 Oct fixed
-# # Fifth EC Directive ???
-# # Summer Time Order, 1989 (SI1989/985)
-# 1990    25 Mar  28 Oct fixed
-# 1991    31 Mar  27 Oct fixed
-# 1992    29 Mar  25 Oct fixed
-# # Sixth EC Directive
-# # Summer Time Order, 1992 (SI1992/1729)
-# 1993    28 Mar  24 Oct fixed
-# 1994    27 Mar  23 Oct fixed
-
-# From Peter Ilieve <peter@memex.co.uk> (1994-08-18):
-# I now have the text of the 7th EC directive on summer time arrangements
-# (94/21/EC), which was approved on 30 May....
-# The major changes from existing practice are that 1995 will be the last year
-# that the UK and Eire finish on a different date from everyone else,
-# and the common end date from 1996 onwards will be the last Sunday in October.
-# Year	 Start		End		End (UK & Eire, 1995 only)
-# (rule) (last Sun)	(last Sun)	(4th Sun)
-# 1995	26 March	24 September	22 October
-# 1996	31 March	27 October
-# 1997	30 March	26 October
-#
-# From Peter Ilieve <peter@memex.co.uk> (1994-12-01):
-# The final piece of the legislative jigsaw for summer time in the UK for
-# 1995-97 is now in place.  The Summer Time Order 1994 (SI 1994/2798)
-# came into force on 16 November.  It restates the dates from the EC
-# seventh Summer Time Directive....
-#
-# From Peter Ilieve <peter@aldie.co.uk> (1996-04-20):
-# Proposals for the eighth directive were supposed to have been produced
-# by the Commission by 1 Jan 96. They have not yet appeared (I asked just
-# before Easter).
-
-# From Peter Ilieve <peter@memex.co.uk> (1994-03-28):
-# The [GB-Eire] end date of 22 October [1995] conflicts with your current rule
-# of Oct Sun>=23, and the historical UK formula of Sun after 4th Sat.
-# The last time 4th Sun and Sun after 4th Sat differed was in 1989,
-# when 29 October was used.  That year was covered by a UK Summer Time Order
-# for only a single year and it looks as though there was a matching 4th EC
-# directive for just this year.  I don't have the text of the 5th EC
-# directive (for 1990--92) but my guess would be it said 4th Sun.
-# To maintain strict historical accuracy you could start a new UK ending rule
-# of Oct Sun>=22 in 1990.
-
-# From Paul Eggert <eggert@twinsun.com> (1996-06-12):
-#
-# As Ilieve remarks, the date `20 April 1924' in the table of ``Summer Time: A
-# Consultation Document'' (Cm 722, 1989) table is a transcription error;
-# 20 April was an Easter Sunday.  Shanks has 13 April, the correct date.
-# Also, the table is not quite right for 1925 through 1938; the correct rules
-# (which Shanks uses) are given in the Summer Time Acts of 1922 and 1925.
-# Shanks and the UK Government paper disagree about the Apr 1956 transition;
-# since we have no other data, and since Shanks was correct in the other
-# points of disagreement about London, we'll believe Shanks for now.
-# Also, for lack of other data, we'll follow Shanks for Eire in 1940-1948.
-#
-# Given Peter Ilieve's comments, the following claims by Shanks are incorrect:
-#     * Wales did not switch from GMT to daylight savings time until
+# From Joseph S. Myers (1999-09-02):
+# ... some military cables (WO 219/4100 - this is a copy from the
+# main SHAEF archives held in the US National Archives, SHAEF/5252/8/516)
+# agree that the usage is BDST (this appears in a message dated 17 Feb 1945).
+
+# From Joseph S. Myers (2000-10-03):
+# On 18th April 1941, Sir Stephen Tallents of the BBC wrote to Sir
+# Alexander Maxwell of the Home Office asking whether there was any
+# official designation; the reply of the 21st was that there wasn't
+# but he couldn't think of anything better than the "Double British
+# Summer Time" that the BBC had been using informally.
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/bbc-19410418.png
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/ho-19410421.png
+
+# From Sir Alexander Maxwell in the above-mentioned letter (1941-04-21):
+# [N]o official designation has as far as I know been adopted for the time
+# which is to be introduced in May....
+# I cannot think of anything better than "Double British Summer Time"
+# which could not be said to run counter to any official description.
+
+# From Paul Eggert (2000-10-02):
+# Howse writes (p 157) `DBST' too, but `BDST' seems to have been common
+# and follows the more usual convention of putting the location name first,
+# so we use `BDST'.
+
+# Peter Ilieve <peter@aldie.co.uk> (1998-04-19) described at length
+# the history of summer time legislation in the United Kingdom.
+# Since 1998 Joseph S. Myers <jsm28@cam.ac.uk> has been updating
+# and extending this list, which can be found in
+# <a href="http://student.cusu.cam.ac.uk/~jsm28/british-time/">
+# History of legal time in Britain
+# </a> (2000-02-12).
+
+# From Joseph S. Myers <jsm28@cam.ac.uk> (1998-01-06):
+#
+# The legal time in the UK outside of summer time is definitely GMT, not UTC;
+# see Lord Tanlaw's speech
+# <a href="http://www.parliament.the-stationery-office.co.uk/pa/ld199697/ldhansrd/pdvn/lds97/text/70611-20.htm#70611-20_head0">
+# (Lords Hansard 11 June 1997 columns 964 to 976)
+# </a>.
+
+# From Paul Eggert (2000-02-17):
+#
+# For lack of other data, we'll follow Shanks for Eire in 1940-1948.
+#
+# Given Ilieve and Myers's data, the following claims by Shanks are incorrect:
+#     * Wales did not switch from GMT to daylight saving time until
 #	1921 Apr 3, when they began to conform with the rest of Great Britain.
 # Actually, Wales was identical after 1880.
 #     * Eire had two transitions on 1916 Oct 1.
 # It actually just had one transition.
-#     * Northern Ireland used single daylight savings time throughout WW II.
+#     * Northern Ireland used single daylight saving time throughout WW II.
 # Actually, it conformed to Britain.
 #     * GB-Eire changed standard time to 1 hour ahead of GMT on 1968-02-18.
 # Actually, that date saw the usual switch to summer time.
 # Standard time was not changed until 1968-10-27 (the clocks didn't change).
 #
-# The following claims by Shanks are possible though doubtful;
-# we'll ignore them for now.
+# Here is another incorrect claim by Shanks:
 #     * Jersey, Guernsey, and the Isle of Man did not switch from GMT
-#	to daylight savings time until 1921 Apr 3, when they began to
+#	to daylight saving time until 1921 Apr 3, when they began to
 #	conform with Great Britain.
+# S.R.&O. 1916, No. 382 and HO 45/10811/312364 (quoted above) say otherwise.
+#
+# The following claim by Shanks is possible though doubtful;
+# we'll ignore it for now.
 #     * Dublin's 1971-10-31 switch was at 02:00, even though London's was 03:00.
 #
 #
 # Whitman says Dublin Mean Time was -0:25:21, which is more precise than Shanks.
 
+# From Paul Eggert (1999-03-28):
+# Clive Feather (<news:859845706.26043.0@office.demon.net>, 1997-03-31)
+# reports that Folkestone (Cheriton) Shuttle Terminal uses Concession Time
+# (CT), equivalent to French civil time.
+# Julian Hill (<news:36118128.5A14@virgin.net>, 1998-09-30) reports that
+# trains between Dollands Moor (the freight facility next door)
+# and Frethun run in CT.
+# My admittedly uninformed guess is that the terminal has two authorities,
+# the French concession operators and the British civil authorities,
+# and that the time depends on who you're talking to.
+# If, say, the British police were called to the station for some reason,
+# I would expect the official police report to use GMT/BST and not CET/CEST.
+# This is a borderline case, but for now let's stick to GMT/BST.
+
 # From an anonymous contributor (1996-06-02):
 # The law governing time in Ireland is under Statutory Instrument SI 395/94,
 # which gives force to European Union 7th Council Directive # 94/21/EC.
@@ -690,97 +257,131 @@
 # "Irish Summer Time", abbreviated to "IST".
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# 1916 to 1925--irregular
+# Summer Time Act, 1916
 Rule	GB-Eire	1916	only	-	May	21	2:00s	1:00	BST
 Rule	GB-Eire	1916	only	-	Oct	 1	2:00s	0	GMT
+# S.R.&O. 1917, No. 358
 Rule	GB-Eire	1917	only	-	Apr	 8	2:00s	1:00	BST
 Rule	GB-Eire	1917	only	-	Sep	17	2:00s	0	GMT
+# S.R.&O. 1918, No. 274
 Rule	GB-Eire	1918	only	-	Mar	24	2:00s	1:00	BST
 Rule	GB-Eire	1918	only	-	Sep	30	2:00s	0	GMT
+# S.R.&O. 1919, No. 297
 Rule	GB-Eire	1919	only	-	Mar	30	2:00s	1:00	BST
 Rule	GB-Eire	1919	only	-	Sep	29	2:00s	0	GMT
+# S.R.&O. 1920, No. 458
 Rule	GB-Eire	1920	only	-	Mar	28	2:00s	1:00	BST
+# S.R.&O. 1920, No. 1844
 Rule	GB-Eire	1920	only	-	Oct	25	2:00s	0	GMT
+# S.R.&O. 1921, No. 363
 Rule	GB-Eire	1921	only	-	Apr	 3	2:00s	1:00	BST
 Rule	GB-Eire	1921	only	-	Oct	 3	2:00s	0	GMT
+# S.R.&O. 1922, No. 264
 Rule	GB-Eire	1922	only	-	Mar	26	2:00s	1:00	BST
 Rule	GB-Eire	1922	only	-	Oct	 8	2:00s	0	GMT
+# The Summer Time Act, 1922
 Rule	GB-Eire	1923	only	-	Apr	Sun>=16	2:00s	1:00	BST
 Rule	GB-Eire	1923	1924	-	Sep	Sun>=16	2:00s	0	GMT
-Rule	GB-Eire	1924	only	-	Apr	13	2:00s	1:00	BST
-# 1925 to 1939 start--regular, except for avoiding Easter
+Rule	GB-Eire	1924	only	-	Apr	Sun>=9	2:00s	1:00	BST
 Rule	GB-Eire	1925	1926	-	Apr	Sun>=16	2:00s	1:00	BST
+# The Summer Time Act, 1925
 Rule	GB-Eire	1925	1938	-	Oct	Sun>=2	2:00s	0	GMT
-Rule	GB-Eire	1927	only	-	Apr	10	2:00s	1:00	BST
+Rule	GB-Eire	1927	only	-	Apr	Sun>=9	2:00s	1:00	BST
 Rule	GB-Eire	1928	1929	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1930	only	-	Apr	13	2:00s	1:00	BST
+Rule	GB-Eire	1930	only	-	Apr	Sun>=9	2:00s	1:00	BST
 Rule	GB-Eire	1931	1932	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1933	only	-	Apr	 9	2:00s	1:00	BST
+Rule	GB-Eire	1933	only	-	Apr	Sun>=9	2:00s	1:00	BST
 Rule	GB-Eire	1934	only	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1935	only	-	Apr	14	2:00s	1:00	BST
+Rule	GB-Eire	1935	only	-	Apr	Sun>=9	2:00s	1:00	BST
 Rule	GB-Eire	1936	1937	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1938	only	-	Apr	10	2:00s	1:00	BST
+Rule	GB-Eire	1938	only	-	Apr	Sun>=9	2:00s	1:00	BST
 Rule	GB-Eire	1939	only	-	Apr	Sun>=16	2:00s	1:00	BST
-# 1939 end to 1947--irregular, and with double summer time
-Rule	GB-Eire	1939	only	-	Nov	19	2:00s	0	GMT
-Rule	GB-Eire	1940	only	-	Feb	25	2:00s	1:00	BST
+# S.R.&O. 1939, No. 1379
+Rule	GB-Eire	1939	only	-	Nov	Sun>=16	2:00s	0	GMT
+# S.R.&O. 1940, No. 172 and No. 1883
+Rule	GB-Eire	1940	only	-	Feb	Sun>=23	2:00s	1:00	BST
+# S.R.&O. 1941, No. 476
 Rule	GB-Eire	1941	only	-	May	Sun>=2	1:00s	2:00	BDST
 Rule	GB-Eire	1941	1943	-	Aug	Sun>=9	1:00s	1:00	BST
+# S.R.&O. 1942, No. 506
 Rule	GB-Eire	1942	1944	-	Apr	Sun>=2	1:00s	2:00	BDST
+# S.R.&O. 1944, No. 932
 Rule	GB-Eire	1944	only	-	Sep	Sun>=16	1:00s	1:00	BST
-# Double daylight starts on a Monday in 1945--see above.
-Rule	GB-Eire	1945	only	-	Apr	 2	1:00s	2:00	BDST
-Rule	GB-Eire	1945	only	-	Jul	15	1:00s	1:00	BST
-Rule	GB-Eire	1945	only	-	Oct	 7	2:00s	0	GMT
-Rule	GB-Eire	1946	only	-	Apr	14	2:00s	1:00	BST
-Rule	GB-Eire	1946	only	-	Oct	 6	2:00s	0	GMT
+# S.R.&O. 1945, No. 312
+Rule	GB-Eire	1945	only	-	Apr	Mon>=2	1:00s	2:00	BDST
+Rule	GB-Eire	1945	only	-	Jul	Sun>=9	1:00s	1:00	BST
+# S.R.&O. 1945, No. 1208
+Rule	GB-Eire	1945	1946	-	Oct	Sun>=2	2:00s	0	GMT
+Rule	GB-Eire	1946	only	-	Apr	Sun>=9	2:00s	1:00	BST
+# The Summer Time Act, 1947
 Rule	GB-Eire	1947	only	-	Mar	16	2:00s	1:00	BST
 Rule	GB-Eire	1947	only	-	Apr	13	1:00s	2:00	BDST
 Rule	GB-Eire	1947	only	-	Aug	10	1:00s	1:00	BST
 Rule	GB-Eire	1947	only	-	Nov	 2	2:00s	0	GMT
-# So much for double saving time.  1948 and 1949, irregular.
+# Summer Time Order, 1948 (S.I. 1948/495)
 Rule	GB-Eire	1948	only	-	Mar	14	2:00s	1:00	BST
-Rule	GB-Eire	1948	1949	-	Oct	lastSun	2:00s	0	GMT
+Rule	GB-Eire	1948	only	-	Oct	31	2:00s	0	GMT
+# Summer Time Order, 1949 (S.I. 1949/373)
 Rule	GB-Eire	1949	only	-	Apr	 3	2:00s	1:00	BST
-# 1950 through start of 1953, regular.
-Rule	GB-Eire	1950	1953	-	Apr	Sun>=14	2:00s	1:00	BST
+Rule	GB-Eire	1949	only	-	Oct	30	2:00s	0	GMT
+# Summer Time Order, 1950 (S.I. 1950/518)
+# Summer Time Order, 1951 (S.I. 1951/430)
+# Summer Time Order, 1952 (S.I. 1952/451)
+Rule	GB-Eire	1950	1952	-	Apr	Sun>=14	2:00s	1:00	BST
 Rule	GB-Eire	1950	1952	-	Oct	Sun>=21	2:00s	0	GMT
-# 1954 to 1980, starting rules
-Rule	GB-Eire	1954	only	-	Apr	11	2:00s	1:00	BST
+# revert to the rules of the Summer Time Act, 1925
+Rule	GB-Eire	1953	only	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1953	1960	-	Oct	Sun>=2	2:00s	0	GMT
+Rule	GB-Eire	1954	only	-	Apr	Sun>=9	2:00s	1:00	BST
 Rule	GB-Eire	1955	1956	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1957	only	-	Apr	14	2:00s	1:00	BST
+Rule	GB-Eire	1957	only	-	Apr	Sun>=9	2:00s	1:00	BST
 Rule	GB-Eire	1958	1959	-	Apr	Sun>=16	2:00s	1:00	BST
-Rule	GB-Eire	1960	only	-	Apr	10	2:00s	1:00	BST
+Rule	GB-Eire	1960	only	-	Apr	Sun>=9	2:00s	1:00	BST
+# Summer Time Order, 1961 (S.I. 1961/71)
+# Summer Time (1962) Order, 1961 (S.I. 1961/2465)
+# Summer Time Order, 1963 (S.I. 1963/81)
 Rule	GB-Eire	1961	1963	-	Mar	lastSun	2:00s	1:00	BST
+Rule	GB-Eire	1961	1968	-	Oct	Sun>=23	2:00s	0	GMT
+# Summer Time (1964) Order, 1963 (S.I. 1963/2101)
+# Summer Time Order, 1964 (S.I. 1964/1201)
+# Summer Time Order, 1967 (S.I. 1967/1148)
 Rule	GB-Eire	1964	1967	-	Mar	Sun>=19	2:00s	1:00	BST
+# Summer Time Order, 1968 (S.I. 1968/117)
 Rule	GB-Eire	1968	only	-	Feb	18	2:00s	1:00	BST
+# The British Standard Time Act, 1968
+#	(no summer time)
+# The Summer Time Act, 1972
 Rule	GB-Eire	1972	1980	-	Mar	Sun>=16	2:00s	1:00	BST
-# 1953 to 1980, ending rules
-Rule	GB-Eire	1953	1960	-	Oct	Sun>=1	2:00s	0	GMT
-Rule	GB-Eire	1961	1968	-	Oct	Sun>=23	2:00s	0	GMT
 Rule	GB-Eire	1972	1980	-	Oct	Sun>=23	2:00s	0	GMT
-# 1981 on
+# Summer Time Order, 1980 (S.I. 1980/1089)
+# Summer Time Order, 1982 (S.I. 1982/1673)
+# Summer Time Order, 1986 (S.I. 1986/223)
+# Summer Time Order, 1988 (S.I. 1988/931)
 Rule	GB-Eire	1981	1995	-	Mar	lastSun	1:00u	1:00	BST
 Rule	GB-Eire 1981	1989	-	Oct	Sun>=23	1:00u	0	GMT
+# Summer Time Order, 1989 (S.I. 1989/985)
+# Summer Time Order, 1992 (S.I. 1992/1729)
+# Summer Time Order 1994 (S.I. 1994/2798)
 Rule	GB-Eire 1990	1995	-	Oct	Sun>=22	1:00u	0	GMT
+# Summer Time Order 1997 (S.I. 1997/2982)
 # See EU for rules starting in 1996.
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/London	-0:01:15 -	LMT	1847 Sep 22
+Zone	Europe/London	-0:01:15 -	LMT	1847 Dec  1
 			 0:00	GB-Eire	%s	1968 Oct 27
 			 1:00	-	BST	1971 Oct 31 2:00u
 			 0:00	GB-Eire	%s	1996
 			 0:00	EU	GMT/BST
 Zone	Europe/Belfast	-0:23:40 -	LMT	1880 Aug  2
 			-0:25:21 -	DMT	1916 May 21 2:00    # Dublin MT
-			-0:25:21 1:00	IST	1916 Oct  1 3:00    # Irish Summer Time
+			-0:25:21 1:00	IST	1916 Oct  1 2:00s   # Irish Summer Time
 			 0:00	GB-Eire	%s	1968 Oct 27
 			 1:00	-	BST	1971 Oct 31 2:00u
 			 0:00	GB-Eire	%s	1996
 			 0:00	EU	GMT/BST
 Zone	Europe/Dublin	-0:25:21 -	LMT	1880 Aug  2
 			-0:25:21 -	DMT	1916 May 21 2:00    # Dublin MT
-			-0:25:21 1:00	IST	1916 Oct  1 3:00
+			-0:25:21 1:00	IST	1916 Oct  1 2:00s
 			 0:00	GB-Eire	%s	1921 Dec  6 # independence
 			 0:00	GB-Eire	GMT/IST	1940 Feb 25 2:00
 			 0:00	1:00	IST	1946 Oct  6 2:00
@@ -806,6 +407,11 @@ Rule	EU	1978	only	-	Oct	 1	 1:00u	0	-
 Rule	EU	1979	1995	-	Sep	lastSun	 1:00u	0	-
 Rule	EU	1981	max	-	Mar	lastSun	 1:00u	1:00	S
 Rule	EU	1996	max	-	Oct	lastSun	 1:00u	0	-
+# The most recent directive covers the years starting in 2002.  See:
+# <a href="http://europa.eu.int/eur-lex/en/lif/dat/2000/en_300L0084.html"
+# Directive 2000/84/EC of the European Parliament and of the Council
+# of 19 January 2001 on summer-time arrangements.
+# </a>
 
 # W-Eur differs from EU only in that W-Eur uses standard time.
 Rule	W-Eur	1977	1980	-	Apr	Sun>=1	 1:00s	1:00	S
@@ -822,7 +428,6 @@ Rule	C-Eur	1916	only	-	Oct	 1	 1:00	0	-
 Rule	C-Eur	1917	1918	-	Apr	Mon>=15	 2:00s	1:00	S
 Rule	C-Eur	1917	1918	-	Sep	Mon>=15	 2:00s	0	-
 Rule	C-Eur	1940	only	-	Apr	 1	 2:00s	1:00	S
-# Whitman says 1941 DST was only from Feb 25 to Oct 5; go with Shanks.
 Rule	C-Eur	1942	only	-	Nov	 2	 2:00s	0	-
 Rule	C-Eur	1943	only	-	Mar	29	 2:00s	1:00	S
 Rule	C-Eur	1943	only	-	Oct	 4	 2:00s	0	-
@@ -848,21 +453,22 @@ Rule	E-Eur	1996	max	-	Oct	lastSun	 0:00	0	-
 Rule	Russia	1917	only	-	Jul	 1	23:00	1:00	MST	# Moscow Summer Time
 Rule	Russia	1917	only	-	Dec	28	 0:00	0	MMT	# Moscow Mean Time
 Rule	Russia	1918	only	-	May	31	22:00	2:00	MDST	# Moscow Double Summer Time
-Rule	Russia	1918	only	-	Sep	17	 0:00	1:00	MST
+Rule	Russia	1918	only	-	Sep	16	 1:00	1:00	MST
 Rule	Russia	1919	only	-	May	31	23:00	2:00	MDST
 Rule	Russia	1919	only	-	Jul	 1	 2:00	1:00	S
 Rule	Russia	1919	only	-	Aug	16	 0:00	0	-
 Rule	Russia	1921	only	-	Feb	14	23:00	1:00	S
-# Shanks gives 1921 Mar 21 for the following transition.
-# From Andrey A. Chernov <ache@astral.msk.su> (1993-11-12):
-# My sources says, that it is Mar 20, not 21.
-Rule	Russia	1921	only	-	Mar	20	23:00	2:00	DS
+Rule	Russia	1921	only	-	Mar	20	23:00	2:00	M # Midsummer
 Rule	Russia	1921	only	-	Sep	 1	 0:00	1:00	S
 Rule	Russia	1921	only	-	Oct	 1	 0:00	0	-
+# Act No.925 of the Council of Ministers of the USSR (1980-10-24):
 Rule	Russia	1981	1984	-	Apr	 1	 0:00	1:00	S
 Rule	Russia	1981	1983	-	Oct	 1	 0:00	0	-
+# Act No.967 of the Council of Ministers of the USSR (1984-09-13), repeated in
+# Act No.227 of the Council of Ministers of the USSR (1989-03-14):
 Rule	Russia	1984	1991	-	Sep	lastSun	 2:00s	0	-
 Rule	Russia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
+#
 Rule	Russia	1992	only	-	Mar	lastSat	 23:00	1:00	S
 Rule	Russia	1992	only	-	Sep	lastSat	 23:00	0	-
 Rule	Russia	1993	max	-	Mar	lastSun	 2:00s	1:00	S
@@ -931,12 +537,10 @@ Rule	Albania	1982	only	-	Oct	 3	0:00	0	-
 Rule	Albania	1983	only	-	Apr	18	0:00	1:00	S
 Rule	Albania	1983	only	-	Oct	 1	0:00	0	-
 Rule	Albania	1984	only	-	Apr	 1	0:00	1:00	S
-Rule	Albania	1984	only	-	Oct	 1	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Tirane	1:19:20 -	LMT	1914
 			1:00	-	CET	1940 Jun 16
-			1:00	Albania	CE%sT	1985 Mar 31 1:00
-			1:00	W-Eur	CE%sT	1991
+			1:00	Albania	CE%sT	1984 Jul
 			1:00	EU	CE%sT
 
 # Andorra
@@ -967,73 +571,91 @@ Zone	Europe/Vienna	1:05:20 -	LMT	1893 Apr
 # Belarus
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Minsk	1:50:16 -	LMT	1880
-			2:30:20	Russia	%s	1919 Jul 1 2:00
-			3:00	Russia	MSK/MSD	1922 Oct
+			1:50	-	MMT	1924 May 2 # Minsk Mean Time
 			2:00	-	EET	1930 Jun 21
-			3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
+			3:00	-	MSK	1941 Jun 28
+			1:00	C-Eur	CE%sT	1944 Jul  3
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1991 Mar 31 2:00s
 			2:00	1:00	EEST	1991 Sep 29 2:00s
-			2:00	-	EET	1992 Mar 29 0:00
-			2:00	1:00	EEST	1992 Sep 27 0:00
+			2:00	-	EET	1992 Mar 29 0:00s
+			2:00	1:00	EEST	1992 Sep 27 0:00s
 			2:00	Russia	EE%sT
 
 # Belgium
-# Whitman and Shanks disagree; go with Shanks, usually.
+#
+# From Paul Eggert (1997-07-02):
+# Entries from 1918 through 1991 are taken from:
+#	Annuaire de L'Observatoire Royal de Belgique,
+#	Avenue Circulaire, 3, B-1180 BRUXELLES, CLVIIe annee, 1991
+#	(Imprimerie HAYEZ, s.p.r.l., Rue Fin, 4, 1080 BRUXELLES, MCMXC),
+#	pp 8-9.
+# LMT before 1892 was 0:17:30, according to the official journal of Belgium:
+#	Moniteur Belge, Samedi 30 Avril 1892, N.121.
+# Thanks to Pascal Delmoitie <pascal@belnet.be> for these references.
+# The 1918 rules are listed for completeness; they apply to unoccupied Belgium.
+# Assume Brussels switched to WET in 1918 when the armistice took effect.
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# From Whitman:
+Rule	Belgium	1918	only	-	Mar	 9	 0:00s	1:00	S
+Rule	Belgium	1918	1919	-	Oct	Sat>=1	23:00s	0	-
 Rule	Belgium	1919	only	-	Mar	 1	23:00s	1:00	S
-Rule	Belgium	1919	only	-	Oct	 4	23:00s	0	-
-# Shanks gives 1920 Feb 14 23:00s; go with Whitman.
-Rule	Belgium	1920	1921	-	Mar	14	23:00s	1:00	S
+Rule	Belgium	1920	only	-	Feb	14	23:00s	1:00	S
 Rule	Belgium	1920	only	-	Oct	23	23:00s	0	-
+Rule	Belgium	1921	only	-	Mar	14	23:00s	1:00	S
 Rule	Belgium	1921	only	-	Oct	25	23:00s	0	-
 Rule	Belgium	1922	only	-	Mar	25	23:00s	1:00	S
-# Whitman gives 1927 Oct 1 2:00s and 1928 Oct 7 2:00s; go with Shanks.
-Rule	Belgium	1922	1928	-	Oct	Sat>=1	23:00s	0	-
+Rule	Belgium	1922	1927	-	Oct	Sat>=1	23:00s	0	-
 Rule	Belgium	1923	only	-	Apr	21	23:00s	1:00	S
 Rule	Belgium	1924	only	-	Mar	29	23:00s	1:00	S
 Rule	Belgium	1925	only	-	Apr	 4	23:00s	1:00	S
+# DSH writes that a royal decree of 1926-02-22 specified the Sun following 3rd
+# Sat in Apr (except if it's Easter, in which case it's one Sunday earlier),
+# to Sun following 1st Sat in Oct, and that a royal decree of 1928-09-15
+# changed the transition times to 02:00 GMT.
 Rule	Belgium	1926	only	-	Apr	17	23:00s	1:00	S
 Rule	Belgium	1927	only	-	Apr	 9	23:00s	1:00	S
 Rule	Belgium	1928	only	-	Apr	14	23:00s	1:00	S
+Rule	Belgium	1928	1938	-	Oct	Sun>=2	 2:00s	0	-
 Rule	Belgium	1929	only	-	Apr	21	 2:00s	1:00	S
-Rule	Belgium	1929	1938	-	Oct	Sun>=2	 2:00s	0	-
 Rule	Belgium	1930	only	-	Apr	13	 2:00s	1:00	S
 Rule	Belgium	1931	only	-	Apr	19	 2:00s	1:00	S
-Rule	Belgium	1932	only	-	Apr	17	 2:00s	1:00	S
+Rule	Belgium	1932	only	-	Apr	 3	 2:00s	1:00	S
 Rule	Belgium	1933	only	-	Mar	26	 2:00s	1:00	S
 Rule	Belgium	1934	only	-	Apr	 8	 2:00s	1:00	S
 Rule	Belgium	1935	only	-	Mar	31	 2:00s	1:00	S
 Rule	Belgium	1936	only	-	Apr	19	 2:00s	1:00	S
-# Whitman says 1937 Apr 18 2:00s; go with Shanks.
 Rule	Belgium	1937	only	-	Apr	 4	 2:00s	1:00	S
-# Whitman says 1938 Apr 10 2:00s; go with Shanks.
 Rule	Belgium	1938	only	-	Mar	27	 2:00s	1:00	S
 Rule	Belgium	1939	only	-	Apr	16	 2:00s	1:00	S
 Rule	Belgium	1939	only	-	Nov	19	 2:00s	0	-
+Rule	Belgium	1940	only	-	Feb	25	 2:00s	1:00	S
+Rule	Belgium	1944	only	-	Sep	17	 2:00s	0	-
 Rule	Belgium	1945	only	-	Apr	 2	 2:00s	1:00	S
 Rule	Belgium	1945	only	-	Sep	16	 2:00s	0	-
 Rule	Belgium	1946	only	-	May	19	 2:00s	1:00	S
 Rule	Belgium	1946	only	-	Oct	 7	 2:00s	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Brussels	0:17:20 -	LMT	1880
-			0:17:20	-	BMT	1892 May  1 12:00 # Brussels MT
-			0:00	-	WET	1914 Aug  4
-			1:00	C-Eur	CE%sT	1919 Mar  1 23:00
-			0:00	Belgium	WE%sT	1940 Feb 24 23:00
-			1:00	C-Eur	CE%sT	1945 Apr  2  2:00
+Zone	Europe/Brussels	0:17:30 -	LMT	1880
+			0:17:30	-	BMT	1892 May  1 12:00 # Brussels MT
+			0:00	-	WET	1914 Nov  8
+			1:00	-	CET	1916 May  1  0:00
+			1:00	C-Eur	CE%sT	1918 Nov 11 11:00u
+			0:00	Belgium	WE%sT	1940 May 20  2:00s
+			1:00	C-Eur	CE%sT	1944 Sep  3
 			1:00	Belgium	CE%sT	1977
 			1:00	EU	CE%sT
 
 # Bosnia and Herzegovina
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Sarajevo	1:13:40	-	LMT	1884
-			1:00	-	CET	1941 Apr 18 23:00
-			1:00	C-Eur	CE%sT	1945 May  8  2:00s
-			1:00	1:00	CEST	1945 Sep 16  2:00s
-			1:00	-	CET	1983
-			1:00	EU	CE%sT
+# see Yugoslavia
 
 # Bulgaria
+#
+# From Plamen Simenov <P.Simeonov@cnsys.bg> via Steffen Thorsen (1999-09-09):
+# A document of Government of Bulgaria (No.94/1997) says:
+# EET --> EETDST is in 03:00 Local time in last Sunday of March ...
+# EETDST --> EET is in 04:00 Local time in last Sunday of October
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Bulg	1979	only	-	Mar	31	23:00	1:00	S
 Rule	Bulg	1979	only	-	Oct	 1	 1:00	0	-
@@ -1048,19 +670,13 @@ Zone	Europe/Sofia	1:33:16 -	LMT	1880
 			2:00	-	EET	1979 Mar 31 23:00
 			2:00	Bulg	EE%sT	1982 Sep 26  2:00
 			2:00	C-Eur	EE%sT	1991
-			2:00	E-Eur	EE%sT
+			2:00	E-Eur	EE%sT	1997
+			2:00	EU	EE%sT
 
 # Croatia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Zagreb	1:03:52	-	LMT	1884
-			1:00	-	CET	1941 Apr 18 23:00
-			1:00	C-Eur	CE%sT	1945 May  8  2:00s
-			1:00	1:00	CEST	1945 Sep 16  2:00s
-			1:00	-	CET	1983
-			1:00	EU	CE%sT
+# see Yugosloavia
 
 # Czech Republic
-# Gregorian calendar adopted 1584-01-17.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Czech	1945	only	-	Apr	 8	2:00s	1:00	S
 Rule	Czech	1945	only	-	Nov	18	2:00s	0	-
@@ -1076,8 +692,7 @@ Zone	Europe/Prague	0:57:44 -	LMT	1850
 			1:00	Czech	CE%sT	1979
 			1:00	EU	CE%sT
 
-# Denmark
-# Gregorian calendar adopted 1700-03-01.
+# Denmark, Faeroe Islands, and Greenland
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Denmark	1916	only	-	May	14	23:00	1:00	S
 Rule	Denmark	1916	only	-	Sep	30	23:00	0	-
@@ -1118,14 +733,14 @@ Rule	Thule	1993	max	-	Apr	Sun>=1	2:00	1:00	D
 Rule	Thule	1993	max	-	Oct	lastSun	2:00	0	S
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Scoresbysund -1:29:00 -	LMT	1916 Jul 28 # Ittoqqortoormit
+Zone America/Scoresbysund -1:29:00 -	LMT	1916 Jul 28 # Ittoqqortoormiit
 			-2:00	-	CGT	1980 Apr  6 2:00
 			-2:00	C-Eur	CG%sT	1981 Mar 29
 			-1:00	EU	EG%sT
 Zone America/Godthab	-3:26:56 -	LMT	1916 Jul 28 # Nuuk
 			-3:00	-	WGT	1980 Apr  6 2:00
 			-3:00	EU	WG%sT
-Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28 # Pituffik
+Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28 # Pituffik air base
 			-4:00	Thule	A%sT
 
 # Estonia
@@ -1143,6 +758,32 @@ Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28 # Pituffik
 # A discussion is running about the summer time efficiency and effect on
 # human physiology.  It seems that Estonia maybe will not change to
 # summer time next spring.''
+
+# From Peter Ilieve <peter@aldie.co.uk> (1998-11-04), heavily edited:
+# <a href="http://trip.rk.ee/cgi-bin/thw?${BASE}=akt&${OOHTML}=rtd&TA=1998&TO=1&AN=1390">
+# The 1998-09-22 Estonian time law
+# </a>
+# refers to the Eighth Directive and cites the association agreement between
+# the EU and Estonia, ratified by the Estonian law (RT II 1995, 22--27, 120).
+#
+# I also asked [my relative] whether they use any standard abbreviation
+# for their standard and summer times. He says no, they use "suveaeg"
+# (summer time) and "talveaeg" (winter time).
+
+# From <a href="http://www.baltictimes.com/">The Baltic Times</a> (1999-09-09)
+# via Steffen Thorsen:
+# This year will mark the last time Estonia shifts to summer time,
+# a council of the ruling coalition announced Sept. 6....
+# But what this could mean for Estonia's chances of joining the European
+# Union are still unclear.  In 1994, the EU declared summer time compulsory
+# for all member states until 2001.  Brussels has yet to decide what to do
+# after that.
+
+# From Mart Oruaas (2000-01-29):
+# Regulation no. 301 (1999-10-12) obsoletes previous regulation
+# no. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all
+# the year round.  The regulation is effective 1999-11-01.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Tallinn	1:39:00	-	LMT	1880
 			1:39:00	-	TMT	1918 Feb # Tallinn Mean Time
@@ -1153,10 +794,11 @@ Zone	Europe/Tallinn	1:39:00	-	LMT	1880
 			1:00	C-Eur	CE%sT	1944 Sep 22
 			3:00	Russia	MSK/MSD	1989 Mar 26 2:00s
 			2:00	1:00	EEST	1989 Sep 24 2:00s
-			2:00	C-Eur	EE%sT
+			2:00	C-Eur	EE%sT	1998 Sep 22
+			2:00	EU	EE%sT	1999 Nov  1
+			2:00	-	EET
 
 # Finland
-# See Sweden for when the Gregorian calendar was adopted.
 #
 # From Hannu Strang <chs@apu.fi> (25 Sep 1994 06:03:37 UTC):
 # Well, here in Helsinki we're just changing from summer time to regular one,
@@ -1176,14 +818,24 @@ Zone	Europe/Helsinki	1:39:52 -	LMT	1878 May 31
 			2:00	EU	EE%sT
 
 # France
-# Gregorian calendar adopted 1582-12-20.
-# French Revolutionary calendar used 1792-09-22 - 1805-12-31.
+
+# From Ciro Discepolo (2000-12-20):
+#
+# Henri Le Corre, Regimes Horaires pour le monde entier, Editions
+# Traditionnelles - Paris 2 books, 1993
+#
+# Gabriel, Traite de l'heure dans le monde, Guy Tredaniel editeur,
+# Paris, 1991
+#
+# Francoise Gauquelin, Problemes de l'heure resolus en astrologie,
+# Guy tredaniel, Paris 1987
+
+
 #
 # Shanks seems to use `24:00' ambiguously; we resolve it with Whitman.
-# From Shanks (1991):
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	France	1916	only	-	Jun	14	23:00s	1:00	S
-Rule	France	1916	1919	-	Oct	Sun>=1	 0:00	0	-
+Rule	France	1916	1919	-	Oct	Sun>=1	23:00s	0	-
 Rule	France	1917	only	-	Mar	24	23:00s	1:00	S
 Rule	France	1918	only	-	Mar	 9	23:00s	1:00	S
 Rule	France	1919	only	-	Mar	 1	23:00s	1:00	S
@@ -1192,6 +844,9 @@ Rule	France	1920	only	-	Oct	23	23:00s	0	-
 Rule	France	1921	only	-	Mar	14	23:00s	1:00	S
 Rule	France	1921	only	-	Oct	25	23:00s	0	-
 Rule	France	1922	only	-	Mar	25	23:00s	1:00	S
+# DSH writes that a law of 1923-05-24 specified 3rd Sat in Apr at 23:00 to 1st
+# Sat in Oct at 24:00; and that in 1930, because of Easter, the transitions
+# were Apr 12 and Oct 5.  Go with Shanks.
 Rule	France	1922	1938	-	Oct	Sat>=1	23:00s	0	-
 Rule	France	1923	only	-	May	26	23:00s	1:00	S
 Rule	France	1924	only	-	Mar	29	23:00s	1:00	S
@@ -1212,45 +867,73 @@ Rule	France	1938	only	-	Mar	26	23:00s	1:00	S
 Rule	France	1939	only	-	Apr	15	23:00s	1:00	S
 Rule	France	1939	only	-	Nov	18	23:00s	0	-
 Rule	France	1940	only	-	Feb	25	 2:00	1:00	S
-# The French rules for 1941-1944 were not used in Paris,
-# but were used in other places (e.g. Monaco).
-Rule	France	1941	only	-	May	 5	 0:00	2:00	DS
-Rule	France	1941	only	-	Oct	 6	 1:00	1:00	S
-Rule	France	1942	only	-	Mar	 8	 0:00	2:00	DS
+# The French rules for 1941-1944 were not used in Paris, but Shanks writes
+# that they were used in Monaco and in many French locations.
+# Le Corre writes that the upper limit of the free zone was Arneguy, Orthez,
+# Mont-de-Marsan, Bazas, Langon, Lamotte-Montravel, Marouil, La
+# Rochefoucault, Champagne-Mouton, La Roche-Posay, La Haye-Decartes,
+# Loches, Montrichard, Vierzon, Bourges, Moulins, Digoin,
+# Paray-le-Monial, Montceau-les-Mines, Chalons-sur-Saone, Arbois,
+# Dole, Morez, St-Claude, and Collognes (Haute-Savioe).
+Rule	France	1941	only	-	May	 5	 0:00	2:00	M # Midsummer
+# Shanks says this transition occurred at Oct 6 1:00,
+# but go with Denis.Excoffier@ens.fr (1997-12-12),
+# who quotes the Ephemerides Astronomiques for 1998 from Bureau des Longitudes
+# as saying 5/10/41 22hUT.
+Rule	France	1941	only	-	Oct	 6	 0:00	1:00	S
+Rule	France	1942	only	-	Mar	 9	 0:00	2:00	M
 Rule	France	1942	only	-	Nov	 2	 3:00	1:00	S
-Rule	France	1943	only	-	Mar	29	 2:00	2:00	DS
-Rule	France	1943	only	-	Nov	 4	 3:00	1:00	S
-Rule	France	1944	only	-	Apr	 3	 2:00	2:00	DS
+Rule	France	1943	only	-	Mar	29	 2:00	2:00	M
+Rule	France	1943	only	-	Oct	 4	 3:00	1:00	S
+Rule	France	1944	only	-	Apr	 3	 2:00	2:00	M
 Rule	France	1944	only	-	Oct	 8	 1:00	1:00	S
-Rule	France	1945	only	-	Apr	 2	 2:00	2:00	DS
+Rule	France	1945	only	-	Apr	 2	 2:00	2:00	M
 Rule	France	1945	only	-	Sep	16	 3:00	0	-
-Rule	France	1976	only	-	Mar	28	 2:00s	1:00	S
-Rule	France	1976	only	-	Sep	lastSun	 2:00s	0	-
+# Shanks gives Mar 28 2:00 and Sep 26 3:00;
+# go with Excoffier's 28/3/76 0hUT and 25/9/76 23hUT.
+Rule	France	1976	only	-	Mar	28	 1:00	1:00	S
+Rule	France	1976	only	-	Sep	26	 1:00	0	-
 # Shanks gives 0:09 for Paris Mean Time, and Whitman gives 0:09:05,
 # but Howse quotes the actual French legislation as saying 0:09:21.
 # Go with Howse.  Howse writes that the time in France was officially based
 # on PMT-0:09:21 until 1978-08-09, when the time base finally switched to UTC.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Paris	0:09:21 -	LMT	1891 Mar 15 0:01
-			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
-			0:00	France	WE%sT	1940 Jun 14
+Zone	Europe/Paris	0:09:21 -	LMT	1891 Mar 15  0:01
+			0:09:21	-	PMT	1911 Mar 11  0:01  # Paris MT
+# Shanks gives 1940 Jun 14 0:00; go with Excoffier and Le Corre.
+			0:00	France	WE%sT	1940 Jun 14 23:00
+# Le Corre says Paris stuck with occupied-France time after the liberation;
+# go with Shanks.
 			1:00	C-Eur	CE%sT	1944 Aug 25
-			0:00	France	WE%sT	1945 Sep 16 3:00
+			0:00	France	WE%sT	1945 Sep 16  3:00
 			1:00	France	CE%sT	1977
 			1:00	EU	CE%sT
 
 # Germany
 
+# From Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> (1998-09-29):
+# The German time zone web site by the Physikalisch-Technische
+# Bundesanstalt contains DST information back to 1916.
+#
+#	<a href="http://www.ptb.de/english/org/4/43/432/lega.htm">
+#	Realisation of Legal Time in Germany
+#	</a>
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Germany	1945	only	-	Apr	 2	2:00s	1:00	S
-Rule	Germany	1945	only	-	May	24	2:00	2:00	DS
-Rule	Germany	1945	only	-	Sep	24	3:00	1:00	S
+# Shanks says 05-24 2:00 to 09-24 3:00 for DDST; go with the PTB, who quotes
+# the Archiv fuer publizist. Arbeit (Munzinger-Archiv) 652 (Zeitsystem)
+# (1961-11-25), which gives dates only.  Guess 3:00 transition times.
+Rule	Germany	1945	only	-	May	31	3:00	2:00	M # Midsummer
+Rule	Germany	1945	only	-	Sep	23	3:00	1:00	S
 Rule	Germany	1945	only	-	Nov	18	2:00s	0	-
 Rule	Germany	1946	only	-	Apr	14	2:00s	1:00	S
-# Whitman gives 1948 Oct 31; go with Shanks.
-Rule	Germany	1946	1949	-	Oct	Sun>=1	2:00s	0	-
+Rule	Germany	1946	only	-	Oct	 7	2:00s	0	-
+Rule	Germany	1947	1949	-	Oct	Sun>=1	2:00s	0	-
 Rule	Germany	1947	only	-	Apr	 6	2:00s	1:00	S
-Rule	Germany	1947	only	-	May	11	2:00s	2:00	DS
+# The PTB gives 3:00 CET and 3:00 CEST for the midsummer transition times;
+# go with Shanks.
+Rule	Germany	1947	only	-	May	11	2:00s	2:00	M
 Rule	Germany	1947	only	-	Jun	29	3:00	1:00	S
 Rule	Germany	1948	only	-	Apr	18	2:00s	1:00	S
 Rule	Germany	1949	only	-	Apr	10	2:00s	1:00	S
@@ -1303,7 +986,6 @@ Zone	Europe/Athens	1:34:52 -	LMT	1895 Sep 14
 			2:00	EU	EE%sT
 
 # Hungary
-# Gregorian calendar adopted 1587-11-01.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Hungary	1918	only	-	Apr	 1	 3:00	1:00	S
 Rule	Hungary	1918	only	-	Sep	29	 3:00	0	-
@@ -1362,10 +1044,10 @@ Zone	Europe/Budapest	1:16:20 -	LMT	1890 Oct
 # might be a reference to the Julian calendar as opposed to Gregorian, or it
 # might mean something else (???).
 #
-# From Paul Eggert <eggert@twinsun.com> (1993-12-09):
+# From Paul Eggert <eggert@twinsun.com> (1999-10-29):
 # The Iceland Almanak, Shanks and Whitman disagree on many points.
 # We go with the Almanak, except for one claim from Shanks, namely that
-# Reykavik was -1:28 from 1837 to 1908, local mean time before that.
+# Reykavik was 21W57 from 1837 to 1908, local mean time before that.
 #
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Iceland	1917	1918	-	Feb	19	23:00	1:00	S
@@ -1395,13 +1077,21 @@ Zone Atlantic/Reykjavik	-1:27:24 -	LMT	1837
 			 0:00	-	GMT
 
 # Italy
-# Gregorian calendar adopted 1582-10-15.
+#
+# From Paul Eggert (2001-03-06):
+# Sicily and Sardinia each had their own time zones from 1866 to 1893,
+# called ``Palermo Time'' (+0053) and ``Cagliari Time'' (+0038).
+# During World War II, German-controlled Italy used German time.
+# But these events all occurred before the 1970 cutoff,
+# so record only the time in Rome.
 #
 # From Paul Eggert (1996-05-06):
 # For Italian DST we have three sources: Shanks, Whitman, and F. Pollastri
-# <URL:http://pisolo.cstv.to.cnr.it/toi/uk/ienitlt.html> (1996-03-14) (`FP'
-# below), taken from an Italian National Electrotechnical Institute publication.
-# When the three sources disagree, guess who's right, as follows:
+# <a href="http://toi.iriti.cnr.it/uk/ienitlt.html">
+# Day-light Saving Time in Italy (1996-03-14)
+# </a>
+# (`FP' below), taken from an Italian National Electrotechnical Institute
+# publication. When the three sources disagree, guess who's right, as follows:
 #
 # year	FP	Shanks (S)	Whitman (W)	Go with:
 # 1916	06-03	06-03 24:00	06-03 00:00	FP & W
@@ -1469,14 +1159,65 @@ Link	Europe/Rome	Europe/Vatican
 Link	Europe/Rome	Europe/San_Marino
 
 # Latvia
-# From Paul Eggert (1996-11-22):
-# Rules after 1991 are by extension from Shanks.  They contradict
-# IATA SSIM (1992/1996), which claims Latvia uses W-Eur rules, but
-# Peter Ilieve's relative writes that Latvia switched in September this year,
-# so we'll assume that the old C-Eur-style rules still apply.
+
+# From Liene Kanepe <Liene_Kanepe@lm.gov.lv> (1998-09-17):
+
+# I asked about this matter Scientific Secretary of the Institute of Astronomy
+# of The University of Latvia Dr. paed Mr. Ilgonis Vilks. I also searched the
+# correct data in juridical acts and I found some juridical documents about
+# changes in the counting of time in Latvia from 1981....
+#
+# Act No.35 of the Council of Ministers of Latvian SSR of 1981-01-22 ...
+# according to the Act No.925 of the Council of Ministers of USSR of 1980-10-24
+# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
+# the hands of the clock 1 hour forward on 1 April at 00:00 (GMT 31 March 21:00)
+# and 1 hour backward on the 1 October at 00:00 (GMT 30 September 20:00).
+#
+# Act No.592 of the Council of Ministers of Latvian SSR of 1984-09-24 ...
+# according to the Act No.967 of the Council of Ministers of USSR of 1984-09-13
+# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
+# the hands of the clock 1 hour forward on the last Sunday of March at 02:00
+# (GMT 23:00 on the previous day) and 1 hour backward on the last Sunday of
+# September at 03:00 (GMT 23:00 on the previous day).
+#
+# Act No.81 of the Council of Ministers of Latvian SSR of 1989-03-22 ...
+# according to the Act No.227 of the Council of Ministers of USSR of 1989-03-14
+# ...: since the last Sunday of March 1989 in Lithuanian SSR, Latvian SSR,
+# Estonian SSR and Kaliningrad region of Russian Federation all year round the
+# time of 2nd time zone (Moscow time minus one hour). On the territory of Latvia
+# transition to summer time is performed on the last Sunday of March at 02:00
+# (GMT 00:00), turning the hands of the clock 1 hour forward.  The end of
+# daylight saving time is performed on the last Sunday of September at 03:00
+# (GMT 00:00), turning the hands of the clock 1 hour backward. Exception is
+# 1989-03-26, when we must not turn the hands of the clock....
+#
+# The Regulations of the Cabinet of Ministers of the Republic of Latvia of
+# 1997-01-21 on transition to Summer time ... established the same order of
+# daylight savings time settings as in the States of the European Union.
+
+# From Andrei Ivanov (2000-03-06):
+# This year Latvia will not switch to Daylight Savings Time (as specified in
+# <a href="http://www.lv-laiks.lv/wwwraksti/2000/071072/vd4.htm">
+# The Regulations of the Cabinet of Ministers of the Rep. of Latvia of
+# 29-Feb-2000 (#79)</a>, in Latvian for subscribers only).
+
+# <a href="http://www.rferl.org/newsline/2001/01/3-CEE/cee-030101.html">
+# From RFE/RL Newsline (2001-01-03), noted after a heads-up by Rives McDow:
+# </a>
+# The Latvian government on 2 January decided that the country will
+# institute daylight-saving time this spring, LETA reported.
+# Last February the three Baltic states decided not to turn back their
+# clocks one hour in the spring....
+# Minister of Economy Aigars Kalvitis noted that Latvia had too few
+# daylight hours and thus decided to comply with a draft European
+# Commission directive that provides for instituting daylight-saving
+# time in EU countries between 2002 and 2006. The Latvian government
+# urged Lithuania and Estonia to adopt a similar time policy, but it
+# appears that they will not do so....
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Latvia	1992	max	-	Mar	lastSun	 2:00s	1:00	S
-Rule	Latvia	1992	max	-	Sep	lastSun	 2:00s	0	-
+Rule	Latvia	1989	1996	-	Mar	lastSun	 2:00s	1:00	S
+Rule	Latvia	1989	1996	-	Sep	lastSun	 2:00s	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Riga	1:36:24	-	LMT	1880
 			1:36:24	-	RMT	1918 Apr 15 2:00 #Riga Mean Time
@@ -1486,10 +1227,13 @@ Zone	Europe/Riga	1:36:24	-	LMT	1880
 			1:36:24	-	RMT	1926 May 11
 			2:00	-	EET	1940 Aug  5
 			3:00	-	MSK	1941 Jul
-			1:00	C-Eur	CE%sT	1944 Aug  8
-			3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
-			2:00	1:00	EEST	1991 Sep 29 2:00s
-			2:00	Latvia	EE%sT
+			1:00	C-Eur	CE%sT	1944 Oct 13
+			3:00	Russia	MSK/MSD	1989 Mar lastSun 2:00s
+			2:00	1:00	EEST	1989 Sep lastSun 2:00s
+			2:00	Latvia	EE%sT	1997 Jan 21
+			2:00	EU	EE%sT	2000 Feb 29
+			2:00	-	EET	2001
+			2:00	EU	EE%sT
 
 # Liechtenstein
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1498,6 +1242,28 @@ Zone	Europe/Vaduz	0:38:04 -	LMT	1894 Jun
 			1:00	EU	CE%sT
 
 # Lithuania
+
+# From Paul Eggert (1996-11-22):
+# IATA SSIM (1992/1996) says Lithuania uses W-Eur rules, but since it is
+# known to be wrong about Estonia and Latvia, assume it's wrong here too.
+
+# From Marius Gedminas <mgedmin@pub.osf.lt> (1998-08-07):
+# I would like to inform that in this year Lithuanian time zone
+# (Europe/Vilnius) was changed.
+
+# From <a href="http://www.elta.lt/">ELTA</a> No. 972 (2582) (1999-09-29),
+# via Steffen Thorsen:
+# Lithuania has shifted back to the second time zone (GMT plus two hours)
+# to be valid here starting from October 31,
+# as decided by the national government on Wednesday....
+# The Lithuanian government also announced plans to consider a
+# motion to give up shifting to summer time in spring, as it was
+# already done by Estonia.
+
+# From the <a href="http://www.tourism.lt/informa/ff.htm">
+# Fact File, Lithuanian State Department of Tourism
+# </a> (2000-03-27): Local time is GMT+2 hours ..., no daylight saving.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Vilnius	1:41:16	-	LMT	1880
 			1:24:00	-	WMT	1917	    # Warsaw Mean Time
@@ -1509,10 +1275,10 @@ Zone	Europe/Vilnius	1:41:16	-	LMT	1880
 			1:00	C-Eur	CE%sT	1944 Aug
 			3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
 			2:00	1:00	EEST	1991 Sep 29 2:00s
-			2:00	C-Eur	EE%sT
-# From Paul Eggert (1996-11-22):
-# IATA SSIM (1992/1996) says Lithuania uses W-Eur rules, but since it is
-# known to be wrong about Estonia and Latvia, assume it's wrong here too.
+			2:00	C-Eur	EE%sT	1998
+			2:00	-	EET	1998 Mar 29 1:00u
+			1:00	EU	CE%sT	1999 Oct 31 1:00u
+			2:00	-	EET
 
 # Luxembourg
 # Whitman disagrees with most of these dates in minor ways; go with Shanks.
@@ -1550,13 +1316,7 @@ Zone Europe/Luxembourg	0:24:36 -	LMT	1904 Jun
 			1:00	EU	CE%sT
 
 # Macedonia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Skopje	1:25:44	-	LMT	1884
-			1:00	-	CET	1941 Apr 18 23:00
-			1:00	C-Eur	CE%sT	1945 May  8  2:00s
-			1:00	1:00	CEST	1945 Sep 16  2:00s
-			1:00	-	CET	1983
-			1:00	EU	CE%sT
+# see Yugoslavia
 
 # Malta
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -1576,12 +1336,32 @@ Zone	Europe/Malta	0:58:04 -	LMT	1893 Nov  2	# Valletta
 			1:00	EU	CE%sT
 
 # Moldova
+
+# From Paul Eggert (2001-02-11):
+# A previous version of this database followed Shanks, who writes that
+# Tiraspol switched to Moscow time on 1992-01-19 at 02:00.
+# However, this is most likely an error, as Moldova declared independence
+# on 1991-08-27 (the 1992-01-19 date is that of a Russian decree).
+# In early 1992 there was large-scale interethnic violence in the area
+# and it's possible that some Russophones continued to observe Moscow time.
+# But moldavizolit@tirastel.md and mk@tirastel.md separately reported via
+# Jesper Norgaard that as of 2001-01-24 Tiraspol was like Chisinau.
+# The Tiraspol entry has therefore been removed for now.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone	Europe/Chisinau	1:55:20 -	LMT	1924 May  2
-			2:00	-	EET	1930 Jun 21
-			3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
-			2:00	1:00	EEST	1991 Sep 29 2:00s
-			2:00	E-Eur	EE%sT
+Zone	Europe/Chisinau	1:55:20 -	LMT	1880
+			1:55	-	CMT	1918 Feb 15 # Chisinau MT
+			1:44:24	-	BMT	1931 Jul 24 # Bucharest MT
+			2:00	Romania	EE%sT	1940 Aug 15
+			2:00	1:00	EEST	1941 Jul 17
+			1:00	C-Eur	CE%sT	1944 Aug 24
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 May 6
+			2:00	-	EET	1991
+			2:00	Russia	EE%sT	1992
+			2:00	E-Eur	EE%sT	1997
+# See Romania commentary for the guessed 1997 transition to EU rules.
+			2:00	EU	EE%sT
 
 # Monaco
 # Shanks gives 0:09 for Paris Mean Time; go with Howse's more precise 0:09:21.
@@ -1595,52 +1375,44 @@ Zone	Europe/Monaco	0:29:32 -	LMT	1891 Mar 15
 # Netherlands
 # Howse writes that the Netherlands' railways used GMT between 1892 and 1940,
 # but for other purposes the Netherlands used Amsterdam mean time.
+# The data before 1945 is taken from
+# <http://www.phys.uu.nl/~vgent/wettijd/wettijd.htm>.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-# Shanks gives 1916 May 1 0:00 and 1916 Oct 1 0:00; go with Whitman.
-Rule	Neth	1916	only	-	May	 1	2:00s	1:00	NST	# Netherlands Summer Time
-Rule	Neth	1916	only	-	Oct	 2	2:00s	0	AMT	# Amsterdam Mean Time
+Rule	Neth	1916	only	-	May	 1	0:00	1:00	NST	# Netherlands Summer Time
+Rule	Neth	1916	only	-	Oct	 1	0:00	0	AMT	# Amsterdam Mean Time
 Rule	Neth	1917	only	-	Apr	16	2:00s	1:00	NST
 Rule	Neth	1917	only	-	Sep	17	2:00s	0	AMT
-# Whitman gives 1918 Apr 14, 1918 Oct 31, and 1921 Sep 28; go with Shanks.
 Rule	Neth	1918	1921	-	Apr	Mon>=1	2:00s	1:00	NST
-Rule	Neth	1918	1921	-	Sep	Mon>=24	2:00s	0	AMT
-Rule	Neth	1922	only	-	Mar	26	2:00s	1:00	NST
-# Whitman gives 1939 Oct 1; go with Shanks.
+Rule	Neth	1918	1921	-	Sep	lastSun	2:00s	0	AMT
+Rule	Neth	1922	only	-	Mar	lastSun	2:00s	1:00	NST
 Rule	Neth	1922	1936	-	Oct	Sun>=2	2:00s	0	AMT
-Rule	Neth	1923	only	-	Jun	 1	2:00s	1:00	NST
-Rule	Neth	1924	only	-	Mar	30	2:00s	1:00	NST
-# Whitman gives 1925 Apr 5; go with Shanks.
-Rule	Neth	1925	only	-	Jun	 5	2:00s	1:00	NST
-# For 1926 through 1930 Whitman gives Apr 15; go with Shanks.
+Rule	Neth	1923	only	-	Jun	Fri>=1	2:00s	1:00	NST
+Rule	Neth	1924	only	-	Mar	lastSun	2:00s	1:00	NST
+Rule	Neth	1925	only	-	Jun	Fri>=1	2:00s	1:00	NST
 Rule	Neth	1926	1931	-	May	15	2:00s	1:00	NST
 Rule	Neth	1932	only	-	May	22	2:00s	1:00	NST
 Rule	Neth	1933	1936	-	May	15	2:00s	1:00	NST
 Rule	Neth	1937	only	-	May	22	2:00s	1:00	NST
 Rule	Neth	1937	only	-	Jul	 1	0:00	1:00	S
 Rule	Neth	1937	1939	-	Oct	Sun>=2	2:00s	0	-
-# Whitman gives 1939 Apr 15 and 1940 Apr 19; go with Shanks.
 Rule	Neth	1938	1939	-	May	15	2:00s	1:00	S
 Rule	Neth	1945	only	-	Apr	 2	2:00s	1:00	S
-Rule	Neth	1945	only	-	May	20	2:00s	0	-
-# Before 1937, Shanks says just `0:20'; we use Whitman's more precise figure.
+Rule	Neth	1945	only	-	Sep	16	2:00s	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Europe/Amsterdam	0:19:28 -	LMT	1892 May
 			0:19:28	Neth	%s	1937 Jul
-			0:20	Neth	NE%sT	1940 May 16 0:40
+			0:20	Neth	NE%sT	1940 May 17 0:00
 			1:00	C-Eur	CE%sT	1945 Apr  2 2:00
 			1:00	Neth	CE%sT	1977
 			1:00	EU	CE%sT
 
 # Norway
-# Gregorian calendar adopted 1700-03-01.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 # Whitman gives 1916 May 21 - 1916 Oct 21; go with Shanks.
 Rule	Norway	1916	only	-	May	22	1:00	1:00	S
 Rule	Norway	1916	only	-	Sep	30	0:00	0	-
-# Shanks omits the following transition; go with Whitman.
-Rule	Norway	1935	only	-	Aug	11	0:00	1:00	S
-# Whitman says DST observed until 1942 Nov 1, then 1943 Mar 29 - Oct 4,
-# 1944 Apr 3 - Oct 2, and 1945 Apr 1 - Oct 1; go with Shanks after 1940.
+# Whitman says DST observed 1935-08-11/1942-11-01, then 1943-03-29/10-04,
+# 1944-04-03/10-02, and 1945-04-01/10-01; go with Shanks.
 Rule	Norway	1945	only	-	Apr	 2	2:00s	1:00	S
 Rule	Norway	1945	only	-	Oct	 1	2:00s	0	-
 Rule	Norway	1959	1964	-	Mar	Sun>=15	2:00s	1:00	S
@@ -1652,11 +1424,9 @@ Zone	Europe/Oslo	0:43:00 -	LMT	1895
 			1:00	C-Eur	CE%sT	1945 Apr  2  2:00
 			1:00	Norway	CE%sT	1980
 			1:00	EU	CE%sT
-#
-# Svalbard
+
+# Svalbard & Jan Mayen
 Link	Europe/Oslo	Arctic/Longyearbyen
-#
-# Jan Mayen
 # From Whitman:
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Atlantic/Jan_Mayen	-1:00	-	EGT
@@ -1692,14 +1462,26 @@ Zone	Europe/Warsaw	1:24:00 -	LMT	1880
 			1:00	Poland	CE%sT	1940 Jun 23 2:00
 			1:00	C-Eur	CE%sT	1944 Oct
 			1:00	Poland	CE%sT	1977 Apr  3 1:00
-			1:00	W-Eur	CE%sT
+			1:00	W-Eur	CE%sT	1999
 # IATA SSIM (1991/1996) gives EU rules, but the _The Warsaw Voice_
-# <URL:http://www.contact.waw.pl/voice/v361/NewsInBrief.shtml>
-# (1995-09-24) says the autumn 1995 switch was at 02:00.
+# <a href="http://www.warsawvoice.com.pl/v361/NewsInBrief.shtml">
+# http://www.warsawvoice.com/pl/v361/NewsInBrief.shtml (1995-09-24)
+# </a>
+# says the autumn 1995 switch was at 02:00.
 # Stick with W-Eur for now.
+#
+# From Marcin.Kasperski@softax.com.pl (1999-06-10):
+# According to my colleagues someone recently decided, that Poland would
+# follow European Union regulations, so - I think - the matter is not
+# worth further discussion.
+#
+# From Paul Eggert (1999-06-10):
+# Kasperski also writes that the government futzed with the rules in 1997
+# or 1998 but he doesn't remember the details.  Assume they switched to
+# EU rules in 1999.
+			1:00	EU	CE%sT
 
 # Portugal
-# Gregorian calendar adopted 1582-10-15.
 #
 # From Rui Pedro Salgueiro <rps@inescca.inescc.pt> (1992-11-12):
 # Portugal has recently (September, 27) changed timezone
@@ -1718,6 +1500,9 @@ Zone	Europe/Warsaw	1:24:00 -	LMT	1880
 # harmonized with the EU), and that they stayed +0:00 that winter.
 #
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# DSH writes that despite Decree 1,469 (1915), the change to the clocks was not
+# done every year, depending on what Spain did, because of railroad schedules.
+# Go with Shanks.
 Rule	Port	1916	only	-	Jun	17	23:00	1:00	S
 # Whitman gives 1916 Oct 31; go with Shanks.
 Rule	Port	1916	only	-	Nov	 1	 1:00	0	-
@@ -1756,12 +1541,12 @@ Rule	Port	1940	only	-	Feb	24	23:00s	1:00	S
 Rule	Port	1940	1941	-	Oct	 5	23:00s	0	-
 Rule	Port	1941	only	-	Apr	 5	23:00s	1:00	S
 Rule	Port	1942	1945	-	Mar	Sat>=8	23:00s	1:00	S
-Rule	Port	1942	only	-	Apr	25	22:00s	2:00	DS
+Rule	Port	1942	only	-	Apr	25	22:00s	2:00	M # Midsummer
 Rule	Port	1942	only	-	Aug	15	22:00s	1:00	S
 Rule	Port	1942	1945	-	Oct	Sat>=24	23:00s	0	-
-Rule	Port	1943	only	-	Apr	17	22:00s	2:00	DS
+Rule	Port	1943	only	-	Apr	17	22:00s	2:00	M
 Rule	Port	1943	1945	-	Aug	Sat>=25	22:00s	1:00	S
-Rule	Port	1944	1945	-	Apr	Sat>=21	22:00s	2:00	DS
+Rule	Port	1944	1945	-	Apr	Sat>=21	22:00s	2:00	M
 Rule	Port	1946	only	-	Apr	Sat>=1	23:00s	1:00	S
 Rule	Port	1946	only	-	Oct	Sat>=1	23:00s	0	-
 Rule	Port	1947	1949	-	Apr	Sun>=1	 2:00s	1:00	S
@@ -1801,6 +1586,14 @@ Zone Atlantic/Madeira	-1:07:36 -	LMT	1884		# Funchal
 			 0:00	EU	WE%sT
 
 # Romania
+#
+# From Paul Eggert (1999-10-07):
+# <a href="http://www.nineoclock.ro/POL/1778pol.html">
+# Nine O'clock</a> (1998-10-23) reports that the switch occurred at
+# 04:00 local time in fall 1998.  For lack of better info,
+# assume that Romania and Moldova switched to EU rules in 1997,
+# the same year as Bulgaria.
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Romania	1932	only	-	May	21	 0:00s	1:00	S
 Rule	Romania	1932	1939	-	Oct	Sun>=1	 0:00s	0	-
@@ -1817,24 +1610,16 @@ Zone Europe/Bucharest	1:44:24 -	LMT	1891 Oct
 			2:00	Romania	EE%sT	1981 Mar 29 2:00s
 			2:00	C-Eur	EE%sT	1991
 			2:00	Romania	EE%sT	1994
-			2:00	E-Eur	EE%sT
+			2:00	E-Eur	EE%sT	1997
+			2:00	EU	EE%sT
 
 # Russia
 
-# From Chris Carrier <72157.3334@CompuServe.COM> (1996-12-02):
-# On 1929-10-01 the Soviet Union instituted an ``Eternal Calendar''
-# with 30-day months plus 5 holidays, with a 5-day week.
-# On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the
-# Gregorian calendar while retaining the 6-day week; on 1940-06-27 it
-# reverted to the 7-day week.  With the 6-day week the usual days
-# off were the 6th, 12th, 18th, 24th and 30th of the month.
-# (Source: Evitiar Zerubavel, _The Seven Day Circle_)
-#
-# From Paul Eggert <eggert@twinsun.com> (1996-11-22):
-# Except for Moscow after 1919-07-01, I invented the time zone abbreviations,
-# and (unless otherwise specified) guessed what happened after 1991.
+# From Paul Eggert <eggert@twinsun.com> (1999-11-12):
+# Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
 # Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
-# are from Andrey A. Chernov.  The rest is from Shanks and the IATA.
+# are from Andrey A. Chernov.  The rest is from Shanks, except we follow
+# Chernov's report that 1992 DST transitions were Sat 23:00, not Sun 02:00s.
 #
 # From Andrey A. Chernov <ache@nagual.ru> (1996-10-04):
 # `MSK' and `MSD' were born and used initially on Moscow computers with
@@ -1847,115 +1632,101 @@ Zone Europe/Bucharest	1:44:24 -	LMT	1891 Oct
 # Moscow to Irkutsk in 1995, public air and rail transport in Russia ...
 # still follows Moscow time, no matter where in Russia it is located.
 #
+# For Grozny, Chechnya, we have the following story from
+# John Daniszewski, "Scavengers in the Rubble", Los Angeles Times (2001-02-07):
+# News--often false--is spread by word of mouth.  A rumor that it was
+# time to move the clocks back put this whole city out of sync with
+# the rest of Russia for two weeks--even soldiers stationed here began
+# enforcing curfew at the wrong time.
+#
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Europe/Kaliningrad	 1:22:00 - 	LMT	1893 Apr
 			 1:00	C-Eur	CE%sT	1945
-			 2:00	Poland	CET	1946
+			 2:00	Poland	CE%sT	1946
 			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
-			 2:00	1:00	EEST	1991 Sep 29 2:00s
-			 2:00	-	EET	1992 Jan 19 2:00s
-			 3:00	Russia	MSK/MSD	1994
-# IATA SSIM (1994-02) says Kaliningrad is at UTC+2; guess 1994 change.
 			 2:00	Russia	EE%sT
 Zone Europe/Moscow	 2:30:20 -	LMT	1880
-			 2:30:20 Russia	%s	1919 Jul  1 2:00
+			 2:30	-	MMT	1916 Jul  3 # Moscow Mean Time
+			 2:30:48 Russia	%s	1919 Jul  1 2:00
 			 3:00	Russia	MSK/MSD	1922 Oct
 			 2:00	-	EET	1930 Jun 21
 			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
-			 2:00	1:00	EEST	1991 Sep 29 2:00s
-			 2:00	-	EET	1992 Jan 19 2:00s
+			 2:00	Russia	EE%sT	1992 Jan 19 2:00s
 			 3:00	Russia	MSK/MSD
-Zone Europe/Samara	 3:20:36 -	LMT	1924 May  2
-			 3:00	-	KUYT	1957 Mar # Kuybyshev Time
-			 4:00	Russia	KUY%sT	1991 Mar 31 2:00s
-			 3:00	1:00	KUYST	1991 Sep 29 2:00s
-			 3:00	-	SAMT	1992 Jan 19 2:00s # Samara Time
-			 4:00	Russia	SAM%sT
-Zone Asia/Yekaterinburg	 4:02:34 -	LMT	1924 May  2
-			 4:00	-	SVET	1957 Mar # Sverdlovsk Time
+Zone Europe/Samara	 3:20:36 -	LMT	1919 Jul  1 2:00
+			 3:00	-	KUYT	1930 Jun 21 # Kuybyshev
+			 4:00	Russia	KUY%sT	1989 Mar 26 2:00s
+			 3:00	Russia	KUY%sT	1991 Mar 31 2:00s
+			 2:00	Russia	KUY%sT	1991 Sep 29 2:00s
+			 3:00	-	KUYT	1991 Oct 20 3:00
+			 4:00	Russia	SAM%sT	# Samara Time
+Zone Asia/Yekaterinburg	 4:02:24 -	LMT	1919 Jul 15 4:00
+			 4:00	-	SVET	1930 Jun 21 # Sverdlovsk Time
 			 5:00	Russia	SVE%sT	1991 Mar 31 2:00s
-			 4:00	1:00	SVEST	1991 Sep 29 2:00s
-			 4:00	-	SVET	1992 Jan 19 2:00s
+			 4:00	Russia	SVE%sT	1992 Jan 19 2:00s
 			 5:00	Russia	YEK%sT	# Yekaterinburg Time
-Zone Asia/Omsk		 4:53:36 -	LMT	1924 May  2
-			 5:00	-	OMST	1957 Mar # Omsk Time
+Zone Asia/Omsk		 4:53:36 -	LMT	1919 Nov 14
+			 5:00	-	OMST	1930 Jun 21 # Omsk TIme
 			 6:00	Russia	OMS%sT	1991 Mar 31 2:00s
-			 5:00	1:00	OMSST	1991 Sep 29 2:00s
-			 5:00	-	OMST	1992 Jan 19 2:00s
+			 5:00	Russia	OMS%sT	1992 Jan 19 2:00s
 			 6:00	Russia	OMS%sT
 # From Stanislaw A. Kuzikowski <S.A.Kuz@iae.nsk.su> (1994-06-29):
 # But now it is some months since Novosibirsk is 3 hours ahead of Moscow!
 # I do not know why they have decided to make this change;
 # as far as I remember it was done exactly during winter->summer switching
 # so we (Novosibirsk) simply did not switch.
-Zone Asia/Novosibirsk	 5:31:40 -	LMT	1924 May  2
-			 6:00	-	NOVT	1957 Mar # Novosibirsk Time
+Zone Asia/Novosibirsk	 5:31:40 -	LMT	1919 Dec 14 6:00
+			 6:00	-	NOVT	1930 Jun 21 # Novosibirsk Time
 			 7:00	Russia	NOV%sT	1991 Mar 31 2:00s
-			 6:00	1:00	NOVST	1991 Sep 29 2:00s
-			 6:00	-	NOVT	1992 Jan 19 2:00s
-			 7:00	Russia	NOV%sT	1994 Mar 27 2:00s
-			 6:00	1:00	NOVST	1994 Sep 25 2:00s
+			 6:00	Russia	NOV%sT	1992 Jan 19 2:00s
+			 7:00	Russia	NOV%sT	1993 May 23 # says Shanks
 			 6:00	Russia	NOV%sT
-Zone Asia/Krasnoyarsk	 6:11:20 -	LMT	1924 May  2
-			 6:00	-	KRAT	1957 Mar # Krasnoyarsk Time
+Zone Asia/Krasnoyarsk	 6:11:20 -	LMT	1920 Jan  6
+			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
 			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
-			 6:00	1:00	KRAST	1991 Sep 29 2:00s
-			 6:00	-	KRAT	1992 Jan 19 2:00s
+			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
 			 7:00	Russia	KRA%sT
 Zone Asia/Irkutsk	 6:57:20 -	LMT	1880
-			 6:57:20 -	IMT	1924 May  2 # Irkutsk Mean Time
-			 7:00	-	IRKT	1957 Mar # Irkutsk Time
+			 6:57:20 -	IMT	1920 Jan 25 # Irkutsk Mean Time
+			 7:00	-	IRKT	1930 Jun 21 # Irkutsk Time
 			 8:00	Russia	IRK%sT	1991 Mar 31 2:00s
-			 7:00	1:00	IRKST	1991 Sep 29 2:00s
-			 7:00	-	IRKT	1992 Jan 19 2:00s
+			 7:00	Russia	IRK%sT	1992 Jan 19 2:00s
 			 8:00	Russia	IRK%sT
-Zone Asia/Yakutsk	 8:38:40 -	LMT	1924 May  2
-			 8:00	-	YAKT	1957 Mar # Yakutsk Time
+Zone Asia/Yakutsk	 8:38:40 -	LMT	1919 Dec 15
+			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
 			 9:00	Russia	YAK%sT	1991 Mar 31 2:00s
-			 8:00	1:00	YAKST	1991 Sep 29 2:00s
-			 8:00	-	YAKT	1992 Jan 19 2:00s
+			 8:00	Russia	YAK%sT	1992 Jan 19 2:00s
 			 9:00	Russia	YAK%sT
-Zone Asia/Vladivostok	 8:47:44 -	LMT	1880
-			 8:47:44 -	VMT	1924 May  2 # Vladivostok MT
-			 9:00	-	VLAT	1957 Mar # Vladivostok Time
+Zone Asia/Vladivostok	 8:47:44 -	LMT	1922 Nov 15
+			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
 			10:00	Russia	VLA%sT	1991 Mar 31 2:00s
-			 9:00	1:00	VLAST	1991 Sep 29 2:00s
-			 9:00	-	VLAT	1992 Jan 19 2:00s
+			 9:00	Russia	VLA%sST	1992 Jan 19 2:00s
 			10:00	Russia	VLA%sT
 Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
-			10:00	-	MAGT	1957 Mar # Magadan Time
+			10:00	-	MAGT	1930 Jun 21 # Magadan Time
 			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
-			10:00	1:00	MAGST	1991 Sep 29 2:00s
-			10:00	-	MAGT	1992 Jan 19 2:00s
+			10:00	Russia	MAG%sT	1992 Jan 19 2:00s
 			11:00	Russia	MAG%sT
 # This name should be Asia/Petropavlovsk-Kamchatski, but that's too long.
-Zone Asia/Kamchatka	10:34:36 -	LMT	1924 May  2
-			11:00	-	PETT	1957 Mar # P-K Time
+Zone Asia/Kamchatka	10:34:36 -	LMT	1922 Nov 10
+			11:00	-	PETT	1930 Jun 21 # P-K Time
 			12:00	Russia	PET%sT	1991 Mar 31 2:00s
-			11:00	1:00	PETST	1991 Sep 29 2:00s
-			11:00	-	PETT	1992 Jan 19 2:00s
+			11:00	Russia	PET%sT	1992 Jan 19 2:00s
 			12:00	Russia	PET%sT
 Zone Asia/Anadyr	11:49:56 -	LMT	1924 May  2
-			12:00	-	ANAT	1957 Mar # Anadyr Time
-			13:00	Russia	ANA%sT	1991 Mar 31 2:00s
-			12:00	1:00	ANAST	1991 Sep 29 2:00s
-			12:00	-	ANAT	1992 Jan 19 2:00s
-			13:00	Russia	ANA%sT
+			12:00	-	ANAT	1930 Jun 21 # Anadyr Time
+			13:00	Russia	ANA%sT	1982 Apr  1 0:00s
+			12:00	Russia	ANA%sT	1991 Mar 31 2:00s
+			11:00	Russia	ANA%sT	1992 Jan 19 2:00s
+			12:00	Russia	ANA%sT
 
 # Slovakia
 Link Europe/Prague Europe/Bratislava
 
 # Slovenia
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone Europe/Ljubljana	0:58:04	-	LMT	1884
-			1:00	-	CET	1941 Apr 18 23:00
-			1:00	C-Eur	CE%sT	1945 May  8  2:00s
-			1:00	1:00	CEST	1945 Sep 16  2:00s
-			1:00	-	CET	1983
-			1:00	EU	CE%sT
+# see Yugoslavia
 
 # Spain
-# Gregorian calendar adopted 1582-10-15.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 # For 1917-1919 Whitman gives Apr Sat>=1 - Oct Sat>=1; go with Shanks.
 Rule	Spain	1917	only	-	May	 5	23:00s	1:00	S
@@ -1979,9 +1750,9 @@ Rule	Spain	1938	only	-	Mar	22	23:00s	1:00	S
 Rule	Spain	1939	only	-	Apr	15	23:00s	1:00	S
 Rule	Spain	1940	only	-	Mar	16	23:00s	1:00	S
 # Whitman says no DST 1942-1945; go with Shanks.
-Rule	Spain	1942	only	-	May	 2	22:00s	2:00	DS
+Rule	Spain	1942	only	-	May	 2	22:00s	2:00	M # Midsummer
 Rule	Spain	1942	only	-	Sep	 1	22:00s	1:00	S
-Rule	Spain	1943	1946	-	Apr	Sat>=13	22:00s	2:00	DS
+Rule	Spain	1943	1946	-	Apr	Sat>=13	22:00s	2:00	M
 Rule	Spain	1943	only	-	Oct	 3	22:00s	1:00	S
 Rule	Spain	1944	only	-	Oct	10	22:00s	1:00	S
 Rule	Spain	1945	only	-	Sep	30	 1:00	1:00	S
@@ -2026,28 +1797,6 @@ Zone	Atlantic/Canary	-1:01:36 -	LMT	1922 Mar # Las Palmas de Gran C.
 # Ignore this for now, as the Canaries are part of the EU.
 
 # Sweden
-
-# From: msb@sq.com (Mark Brader) <URL:news:1996Jul6.012937.29190@sq.com>:
-#
-# In 1700, Denmark made the transition from Julian to Gregorian.  Sweden
-# decided to *start* a transition in 1700 as well, but rather than have one of
-# those unsightly calendar gaps :-), they simply decreed that the next leap
-# year after 1696 would be in 1744 -- putting the whole country on a calendar
-# different from both Julian and Gregorian for a period of 40 years.
-#
-# However, in 1704 something went wrong and the plan was not carried through;
-# they did, after all, have a leap year that year.  And one in 1708.  In 1712
-# they gave it up and went back to Julian, putting 30 days in February that
-# year!...
-#
-# Then in 1753, Sweden made the transition to Gregorian in the usual manner,
-# getting there only 13 years behind the original schedule.
-#
-# (A previous posting of this story was challenged, and Swedish readers
-# produced the following references to support it: "Tiderakning och historia"
-# by Natanael Beckman (1924) and "Tid, en bok om tiderakning och
-# kalendervasen" by Lars-Olof Lode'n (no date was given).)
-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Europe/Stockholm	1:12:12 -	LMT	1878 May 31
 			1:12:12	-	SMT	1900 Jan  1  1:00 # Stockholm MT
@@ -2057,7 +1806,7 @@ Zone Europe/Stockholm	1:12:12 -	LMT	1878 May 31
 			1:00	EU	CE%sT
 
 # Switzerland
-# From Howse (1988), p 82:
+# From Howse:
 # By the end of the 18th century clocks and watches became commonplace
 # and their performance improved enormously.  Communities began to keep
 # mean time in preference to apparent time -- Geneva from 1780 ....
@@ -2065,7 +1814,7 @@ Zone Europe/Stockholm	1:12:12 -	LMT	1878 May 31
 # From Whitman (who writes ``Midnight?''):
 Rule	Swiss	1940	only	-	Nov	 2	0:00	1:00	S
 Rule	Swiss	1940	only	-	Dec	31	0:00	0	-
-# From Shanks (1991):
+# From Shanks:
 Rule	Swiss	1941	1942	-	May	Sun>=1	2:00	1:00	S
 Rule	Swiss	1941	1942	-	Oct	Sun>=1	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -2088,7 +1837,6 @@ Rule	Turkey	1922	only	-	Oct	 8	0:00	0	-
 Rule	Turkey	1924	only	-	May	13	0:00	1:00	S
 Rule	Turkey	1924	1925	-	Oct	 1	0:00	0	-
 Rule	Turkey	1925	only	-	May	 1	0:00	1:00	S
-# Shanks omits the first two transitions in 1940; go with Whitman.
 Rule	Turkey	1940	only	-	Jun	30	0:00	1:00	S
 Rule	Turkey	1940	only	-	Oct	 5	0:00	0	-
 Rule	Turkey	1940	only	-	Dec	 1	0:00	1:00	S
@@ -2139,51 +1887,63 @@ Zone	Europe/Istanbul	1:55:52 -	LMT	1880
 Link	Europe/Istanbul	Asia/Istanbul	# Istanbul is in both continents.
 
 # Ukraine
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Ukraine	1917	only	-	Jul	 1	23:00	1:00	UST	# Ukrainian Summer Time
-Rule	Ukraine	1917	only	-	Dec	28	 0:00	0	KMT	# Kiev Mean Time
-Rule	Ukraine	1918	only	-	May	31	22:00	2:00	UDST	# Ukrainian Double Summer Time
-Rule	Ukraine	1918	only	-	Sep	17	 0:00	1:00	UST
-Rule	Ukraine	1919	only	-	May	31	23:00	2:00	UDST
-Rule	Ukraine	1919	only	-	Jul	 1	 2:00	1:00	UST
-Rule	Ukraine	1919	only	-	Aug	16	 0:00	0	KMT
-Rule	Ukraine	1921	only	-	Feb	14	23:00	1:00	UST
-Rule	Ukraine	1921	only	-	Mar	21	23:00	2:00	UDST
-Rule	Ukraine	1921	only	-	Sep	 1	 0:00	1:00	UST
-Rule	Ukraine	1921	only	-	Oct	 1	 0:00	0	KMT
-Rule	Crimea	1917	only	-	Jul	 1	23:00	1:00	CST	# Crimean Summer Time
-Rule	Crimea	1917	only	-	Dec	28	 0:00	0	NMT	# Nikolayev Mean Time
-Rule	Crimea	1918	only	-	May	31	22:00	2:00	CDST	# Crimean Double Summer Time
-Rule	Crimea	1918	only	-	Sep	17	 0:00	1:00	CST
-Rule	Crimea	1919	only	-	May	31	23:00	2:00	CDST
-Rule	Crimea	1919	only	-	Jul	 1	 2:00	1:00	CST
-Rule	Crimea	1919	only	-	Aug	16	 0:00	0	NMT
-Rule	Crimea	1921	only	-	Feb	14	23:00	1:00	CST
-Rule	Crimea	1921	only	-	Mar	21	23:00	2:00	CDST
-Rule	Crimea	1921	only	-	Sep	 1	 0:00	1:00	CST
-Rule	Crimea	1921	only	-	Oct	 1	 0:00	0	NMT
-Rule	Crimea	1996	max	-	Mar	lastSun	 0:00u	1:00	-
-Rule	Crimea	1996	max	-	Oct	lastSun	 0:00u	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Most of Ukraine since 1970 has been like Kiev.
 Zone Europe/Kiev	2:02:04 -	LMT	1880
-			2:02:04	Ukraine	%s	1924 May  2
+			2:02:04	-	KMT	1924 May  2 # Kiev Mean Time
 			2:00	-	EET	1930 Jun 21
-			3:00	Russia	MSK/MSD	1990 Jul 17
-			2:00	E-Eur	EE%sT	1996
+			3:00	-	MSK	1941 Sep 20
+			1:00	C-Eur	CE%sT	1943 Nov  6
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 Jul  1 2:00
+			2:00	-	EET	1992
+			2:00	E-Eur	EE%sT	1995
+			2:00	EU	EE%sT
+# Ruthenia used CET 1990/1991.
+Zone Europe/Uzhgorod	1:29:12 -	LMT	1890 Oct
+			1:00	-	CET	1940
+			1:00	C-Eur	CE%sT	1944 Oct
+			1:00	1:00	CEST	1944 Oct 26
+			1:00	-	CET	1945 Jun 29
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 Jul  1 2:00
+			1:00	-	CET	1991 Mar 31 3:00
+			2:00	-	EET	1992
+			2:00	E-Eur	EE%sT	1995
 			2:00	EU	EE%sT
+# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
+# Zaporozh'ye has an apostrophe, but Posix file names can't have apostrophes.
+Zone Europe/Zaporozhye	2:20:40 -	LMT	1880
+			2:20	-	CUT	1924 May  2 # Central Ukraine T
+			2:00	-	EET	1930 Jun 21
+			3:00	-	MSK	1941 Aug 25
+			1:00	C-Eur	CE%sT	1943 Oct 25
+			3:00	Russia	MSK/MSD	1991 Mar 31 2:00
+			2:00	E-Eur	EE%sT	1995
+			2:00	EU	EE%sT
+# Central Crimea used Moscow time 1994/1997.
 Zone Europe/Simferopol	2:16:24 -	LMT	1880
-			2:08:00	Crimea	%s	1924 May  2
+			2:16	-	SMT	1924 May  2 # Simferopol Mean T
 			2:00	-	EET	1930 Jun 21
-			3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
-			2:00	1:00	EEST	1991 Sep 29 2:00s
-# From Paul Eggert <eggert@twinsun.com> (1996-10-21):
-# The _Economist_ (1994-05-28, p 45) reports that most of Crimea switched
+			3:00	-	MSK	1941 Nov
+			1:00	C-Eur	CE%sT	1944 Apr 13
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 Jul  1 2:00
+			2:00	-	EET	1992
+# From Paul Eggert <eggert@twinsun.com> (1999-11-12):
+# The _Economist_ (1994-05-28, p 45) reports that central Crimea switched
 # from Kiev to Moscow time sometime after the January 1994 elections.
-# For now, guess it changed Feb 1.
-			2:00	C-Eur	EE%sT	1994 Feb
-# From IATA SSIM (1994/1996), which also says that Kerch is still like Kiev.
-			3:00	E-Eur	MSK/MSD	1996
-			3:00	Crimea	MSK/MSD
+# Shanks says ``date of change uncertain'', but implies that it happened
+# sometime between the 1994 DST switches.  For now, guess it changed in May.
+			2:00	E-Eur	EE%sT	1994 May
+# From IATA SSIM (1994/1997), which also says that Kerch is still like Kiev.
+			3:00	E-Eur	MSK/MSD	1996 Mar 31 3:00s
+			3:00	1:00	MSD	1996 Oct 27 3:00s
+# IATA SSIM (1997-09) says Crimea switched to EET/EEST.
+# Assume it happened in March by not changing the clocks.
+			3:00	Russia	MSK/MSD	1997
+			3:00	-	MSK	1997 Mar lastSun 1:00u
+			2:00	EU	EE%sT
 
 # Yugoslavia
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -2191,8 +1951,15 @@ Zone	Europe/Belgrade	1:22:00	-	LMT	1884
 			1:00	-	CET	1941 Apr 18 23:00
 			1:00	C-Eur	CE%sT	1945 May  8  2:00s
 			1:00	1:00	CEST	1945 Sep 16  2:00s
-			1:00	-	CET	1983
+# Metod Kozelj <metod.kozelj@rzs-hm.si> reports that the legal date of
+# transition to EU rules was 1982-11-27, for all of Yugoslavia at the time.
+# Shanks doesn't give as much detail, so go with Kozelj.
+			1:00	-	CET	1982 Nov 27
 			1:00	EU	CE%sT
+Link Europe/Belgrade Europe/Ljubljana	# Slovenia
+Link Europe/Belgrade Europe/Sarajevo	# Bosnia and Herzegovina
+Link Europe/Belgrade Europe/Skopje	# Macedonia
+Link Europe/Belgrade Europe/Zagreb	# Croatia
 
 ###############################################################################
 
@@ -2269,21 +2036,3 @@ Zone	Europe/Belgrade	1:22:00	-	LMT	1884
 # ...
 # Monaco: has same DST as France.
 # ...
-
-# ...
-# Date: Fri, 3 Sep 93 13:43:41 BST
-# From: Peter Ilieve <peter@memex.co.uk>
-# ...
-# Turning to Europe, I now have a copy of the `Sixth Council Directive 92/20/EEC
-# of 26 March 1992 on summertime arrangements'. This only covers 1993 and
-# 1994, a seventh one is in the works but I doubt that the algorithm will
-# change. This says summertime starts at 01:00 GMT on the last Sunday in March
-# and ends at 01:00 GMT on the last Sunday in September, except for the UK
-# and Eire where it ends at 01:00 GMT on the fourth Sunday in October.
-# It says the arrangements for 1995 onwards will be decided by 1 January 1994,
-# but as the sixth directive was supposed to appear by 1 Jan 92 and didn't
-# arrive til March I wouldn't hold your breath.
-#
-# The first summertime directive was adopted in 1980, although the UK didn't
-# seem to use it until 1981. I suspect it would be safe to move your start
-# dates for the -Eur rules back to 1981.
diff --git a/zic.tproj/datfiles/factory b/zic.tproj/datfiles/factory
index 9d24283..ebcc92b 100644
--- a/zic.tproj/datfiles/factory
+++ b/zic.tproj/datfiles/factory
@@ -1,9 +1,8 @@
-#	$OpenBSD: factory,v 1.2 1997/01/14 04:36:53 millert Exp $
-# @(#)factory	7.1
+# @(#)factory	7.3
 
 # For companies who don't want to put time zone specification in
 # their installation procedures.  When users run date, they'll get the message.
 # Also useful for the "comp.sources" version.
 
 # Zone	NAME	GMTOFF	RULES	FORMAT
-Zone	Factory	0	- "Local time zone must be set--see zic manual page"
+Zone	Factory	0	- "Local time zone must be set--use tzsetup"
diff --git a/zic.tproj/datfiles/leapseconds b/zic.tproj/datfiles/leapseconds
index 279d6bb..390f9cb 100644
--- a/zic.tproj/datfiles/leapseconds
+++ b/zic.tproj/datfiles/leapseconds
@@ -1,10 +1,12 @@
-#	$OpenBSD: leapseconds,v 1.2 1997/01/14 04:36:54 millert Exp $
-# @(#)leapseconds	7.8
+# @(#)leapseconds	7.13
+
+# $FreeBSD: src/share/zoneinfo/leapseconds,v 1.6 2001/04/06 16:46:52 wollman Exp $
 
 # Allowance for leapseconds added to each timezone file.
 
 # The International Earth Rotation Service periodically uses leap seconds
-# to keep UTC to within 0.9 s of TAI (atomic time); see
+# to keep UTC to within 0.9 s of UT1
+# (which measures the true angular orientation of the earth in space); see
 # Terry J Quinn, The BIPM and the accurate measure of time,
 # Proc IEEE 79, 7 (July 1991), 894-905.
 # There were no leap seconds before 1972, because the official mechanism
@@ -18,7 +20,7 @@
 #	Leap	YEAR	MON	DAY	23:59:59	-	R/S
 
 # If the leapsecond is Rolling (R) the given time is local time
-# If the leapsecond is Stationary (S) the given time is GMT
+# If the leapsecond is Stationary (S) the given time is UTC
 
 # Leap	YEAR	MONTH	DAY	HH:MM:SS	CORR	R/S
 Leap	1972	Jun	30	23:59:60	+	S
@@ -41,3 +43,24 @@ Leap	1992	Jun	30	23:59:60	+	S
 Leap	1993	Jun	30	23:59:60	+	S
 Leap	1994	Jun	30	23:59:60	+	S
 Leap	1995	Dec	31	23:59:60	+	S
+Leap	1997	Jun	30	23:59:60	+	S
+Leap	1998	Dec	31	23:59:60	+	S
+# INTERNATIONAL EARTH ROTATION SERVICE (IERS)
+# SERVICE INTERNATIONAL DE LA ROTATION TERRESTRE
+# 
+# SERVICE DE LA ROTATION TERRESTRE
+# OBSERVATOIRE DE PARIS
+# 61, Av. de l'Observatoire 75014 PARIS (France)
+# Tel.      : 33 (0) 1 40 51 22 26
+# FAX       : 33 (0) 1 40 51 22 91
+# Internet  : iers@obspm.fr
+# 
+# Paris, 11 January 2001
+# 
+# Bulletin C 21
+# 
+# To authorities responsible for the measurement and distribution of time
+# 
+# INFORMATION ON UTC - TAI
+# 
+# NO positive leap second will be introduced at the end of June 2001.
diff --git a/zic.tproj/datfiles/northamerica b/zic.tproj/datfiles/northamerica
index ee484cb..8630edb 100644
--- a/zic.tproj/datfiles/northamerica
+++ b/zic.tproj/datfiles/northamerica
@@ -1,20 +1,31 @@
-#	$OpenBSD: northamerica,v 1.5 1997/01/14 04:36:54 millert Exp $
-# @(#)northamerica	7.30
+# @(#)northamerica	7.58
 # also includes Central America and the Caribbean
 
+# $FreeBSD: src/share/zoneinfo/northamerica,v 1.18 2001/04/06 16:46:52 wollman Exp $
+
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
 # tz@elsie.nci.nih.gov for general use in the future).
 
-# From Paul Eggert <eggert@twinsun.com> (1994-08-17):
+# From Paul Eggert <eggert@twinsun.com> (1999-03-22):
 # A reliable and entertaining source about time zones is
-# Derek Howse, Greenwich time and the discovery of the longitude,
-# Oxford University Press (1980).
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 
 ###############################################################################
 
 # United States
 
+# From Paul Eggert (1999-03-31):
+# Howse writes (pp 121-125) that time zones were invented by
+# Professor Charles Ferdinand Dowd (1825-1904),
+# Principal of Temple Grove Ladies' Seminary (Saratoga Springs, NY).
+# His pamphlet ``A System of National Time for Railroads'' (1870)
+# was the result of his proposals at the Convention of Railroad Trunk Lines
+# in New York City (1869-10).  His 1870 proposal was based on Washington, DC,
+# but in 1872-05 he moved the proposed origin to Greenwich.
+# His proposal was adopted by the railroads on 1883-11-18 at 12:00,
+# and the most of the country soon followed suit.
+
 # From Paul Eggert <eggert@twinsun.com> (1995-12-19):
 # A good source for time zone historical data in the US is
 # Thomas G. Shanks, The American Atlas (5th edition),
@@ -22,9 +33,10 @@
 # Make sure you have the errata sheet; the book is somewhat useless without it.
 # It is the source for the US and Puerto Rico entries below.
 
-# From Paul Eggert (1996-06-12):
+# From Paul Eggert (2001-03-06):
 # Daylight Saving Time was first suggested as a joke by Benjamin Franklin
-# in his whimsical essay ``Turkey vs Eagle, McCauley is my Beagle'' (1784).
+# in his whimsical essay ``An Economical Project for Diminishing the Cost
+# of Light'' published in the Journal de Paris (1784-04-26).
 # Not everyone is happy with the results:
 #
 #	I don't really care how time is reckoned so long as there is some
@@ -39,6 +51,16 @@
 #	them healthy, wealthy and wise in spite of themselves.
 #
 #	-- Robertson Davies, The Diary of Samuel Marchbanks (1947), XIX, Sunday
+#
+# For more about the first ten years of DST in the United States, see
+# Robert Garland's <a href="http://www.clpgh.org/exhibit/dst.html">
+# Ten years of daylight saving from the Pittsburgh standpoint
+# (Carnegie Library of Pittsburgh, 1927)</a>.
+#
+# Shanks says that DST was called "War Time" in the US in 1918 and 1919.
+# However, DST was imposed by the Standard Time Act of 1918, which
+# was the first nationwide legal time standard, and apparently
+# time was just called "Standard Time" or "Daylight Saving Time".
 
 # From Arthur David Olson:
 # US Daylight Saving Time ended on the last Sunday of *October* in 1974.
@@ -49,10 +71,30 @@
 # Before the Uniform Time Act of 1966 took effect in 1967, observance of
 # Daylight Saving Time in the US was by local option, except during wartime.
 
+# From Arthur David Olson (2000-09-25):
+# Last night I heard part of a rebroadcast of a 1945 Arch Oboler radio drama.
+# In the introduction, Oboler spoke of "Eastern Peace Time."
+# An AltaVista search turned up
+# <a href="http://rowayton.org/rhs/hstaug45.html">:
+# "When the time is announced over the radio now, it is 'Eastern Peace
+# Time' instead of the old familiar 'Eastern War Time.'  Peace is wonderful."
+# </a> (August 1945) by way of confirmation.
+
+# From Joseph Gallant <notquite@hotmail.com>, citing
+# George H. Douglas, _The Early Days of Radio Broadcasting_ (1987):
+# At 7 P.M. (Eastern War Time) [on 1945-08-14], the networks were set
+# to switch to London for Atlee's address, but the American people
+# never got to hear his speech live. According to one press account,
+# CBS' Bob Trout was first to announce the word of Japan's surrender,
+# but a few seconds later, NBC, ABC and Mutual also flashed the word
+# of surrender, all of whom interrupting the bells of Big Ben in
+# London which were to precede Mr. Atlee's speech.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	US	1918	1919	-	Mar	lastSun	2:00	1:00	W # War
+Rule	US	1918	1919	-	Mar	lastSun	2:00	1:00	D
 Rule	US	1918	1919	-	Oct	lastSun	2:00	0	S
 Rule	US	1942	only	-	Feb	9	2:00	1:00	W # War
+Rule	US	1945	only	-	Aug	14	23:00u	1:00	P # Peace
 Rule	US	1945	only	-	Sep	30	2:00	0	S
 Rule	US	1967	max	-	Oct	lastSun	2:00	0	S
 Rule	US	1967	1973	-	Apr	lastSun	2:00	1:00	D
@@ -60,6 +102,9 @@ Rule	US	1974	only	-	Jan	6	2:00	1:00	D
 Rule	US	1975	only	-	Feb	23	2:00	1:00	D
 Rule	US	1976	1986	-	Apr	lastSun	2:00	1:00	D
 Rule	US	1987	max	-	Apr	Sun>=1	2:00	1:00	D
+# <a href="http://thomas.loc.gov/cgi-bin/bdquery/z?d106:h.r.00177:">
+# H.R.177
+# </a> (introduced 1999-01-06) would change April to March in the above rule.
 
 # From Bob Devine (1988-01-28):
 # ...Alaska (and Hawaii) had the timezone names changed in 1967.
@@ -136,8 +181,28 @@ Rule	US	1987	max	-	Apr	Sun>=1	2:00	1:00	D
 # From Paul Eggert (1995-12-19):
 # Shanks uses 1983-10-30, not 1983-11-30, for the 1983 transitions.
 # Go with Shanks.
+#
+# From Paul Eggert (2000-01-08), following a heads-up from Rives McDow:
+# Public law 106-564 (2000-12-23) introduced the abbreviation
+# "Chamorro Standard Time" for time in Guam and the Northern Marianas.
+# See the file "australasia".
+
+# From Ryan Alessi of the Thousand Oaks Star (2001-02-15) via Rives McDow:
+# Brad Sherman, D-Sherman Oaks, introduced a bill in Congress on
+# Wednesday that could have California operating on Denver time as
+# early as this summer....  The options include keeping
+# daylight-saving time all year long, or setting clocks back two hours
+# -- instead of just one -- during the existing daylight-saving time.
+
 
 # US Eastern time, represented by New York
+
+# Connecticut, Delaware, District of Columbia, most of Florida,
+# Georgia, far southeastern Indiana, eastern Kentucky, Maine,
+# Maryland, Massachusetts, New Hampshire, New Jersey, New York, North
+# Carolina, Ohio, Pennsylvania, Rhode Island, South Carolina, eastern
+# Tennessee, Vermont, Virginia, West Virginia
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
 Rule	NYC	1920	only	-	Mar	lastSun	2:00	1:00	D
 Rule	NYC	1920	only	-	Oct	lastSun	2:00	0	S
@@ -153,6 +218,13 @@ Zone America/New_York	-4:56:02 -	LMT	1883 Nov 18 12:00
 			-5:00	US	E%sT
 
 # US Central time, represented by Chicago
+
+# Alabama, Arkansas, Florida panhandle, Illinois, western Indiana
+# corners, Iowa, most of Kansas, western Kentucky, Louisiana,
+# Minnesota, Mississippi, Missouri, eastern Nebraska, eastern North
+# Dakota, Oklahoma, eastern South Dakota, western Tennessee, most of
+# Texas, Wisconsin
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
 Rule	Chicago	1920	only	-	Jun	13	2:00	1:00	D
 Rule	Chicago	1920	1921	-	Oct	lastSun	2:00	0	S
@@ -171,6 +243,12 @@ Zone America/Chicago	-5:50:36 -	LMT	1883 Nov 18 12:00
 			-6:00	US	C%sT
 
 # US Mountain time, represented by Denver
+#
+# Colorado, southern Idaho, far western Kansas, Montana, western
+# Nebraska, New Mexico, southwestern North Dakota, far eastern Oregon,
+# western South Dakota, far western Texas (El Paso County, Hudspeth County,
+# and Pine Springs and Nickel Creek in Culberson County), Utah, Wyoming
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
 Rule	Denver	1920	1921	-	Mar	lastSun	2:00	1:00	D
 Rule	Denver	1920	only	-	Oct	lastSun	2:00	0	S
@@ -186,6 +264,9 @@ Zone America/Denver	-6:59:56 -	LMT	1883 Nov 18 12:00
 			-7:00	US	M%sT
 
 # US Pacific time, represented by Los Angeles
+#
+# California, northern Idaho, Nevada, most of Oregon, and Washington
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
 Rule	CA	1948	only	-	Mar	14	2:00	1:00	D
 Rule	CA	1949	only	-	Jan	 1	2:00	0	S
@@ -201,40 +282,47 @@ Zone America/Los_Angeles -7:52:58 -	LMT	1883 Nov 18 12:00
 # Alaska
 # AK%sT is the modern abbreviation for -9:00 per USNO.
 #
-# From Paul Eggert (1995-12-19):
+# From Paul Eggert (2001-04-01):
 # Howse writes that Alaska switched from the Julian to the Gregorian calendar,
 # and from east-of-GMT to west-of-GMT days, when the US bought it from Russia.
-# This was on 1867-10-18.  We omit this transition, since we can't represent
-# changes from Julian to Gregorian.
+# This was on 1867-10-18, a Friday; the previous day was 1867-10-06 Julian,
+# also a Friday.  Include only the time zone part of this transition,
+# ignoring the switch from Julian to Gregorian, since we can't represent
+# the Julian calendar.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Juneau	 -8:57:41 -	LMT	1900 Aug 20 12:00
+Zone America/Juneau	 15:02:19 -	LMT	1867 Oct 18
+			 -8:57:41 -	LMT	1900 Aug 20 12:00
 			 -8:00	-	PST	1942
 			 -8:00	US	P%sT	1946
 			 -8:00	-	PST	1969
 			 -8:00	US	P%sT	1983 Oct 30 2:00
 			 -9:00	US	AK%sT
-Zone America/Yakutat	 -9:18:55 -	LMT	1900 Aug 20 12:00
+Zone America/Yakutat	 14:41:05 -	LMT	1867 Oct 18
+			 -9:18:55 -	LMT	1900 Aug 20 12:00
 			 -9:00	-	YST	1942
 			 -9:00	US	Y%sT	1946
 			 -9:00	-	YST	1969
 			 -9:00	US	Y%sT	1983 Oct 30 2:00
 			 -9:00	US	AK%sT
-Zone America/Anchorage	 -9:59:36 -	LMT	1900 Aug 20 12:00
+Zone America/Anchorage	 14:00:24 -	LMT	1867 Oct 18
+			 -9:59:36 -	LMT	1900 Aug 20 12:00
 			-10:00	-	CAT	1942
 			-10:00	US	CAT/CAWT 1946
 			-10:00	-	CAT	1967 Apr
 			-10:00	-	AHST	1969
 			-10:00	US	AH%sT	1983 Oct 30 2:00
 			 -9:00	US	AK%sT
-Zone America/Nome	-11:01:38 -	LMT	1900 Aug 20 12:00
+Zone America/Nome	 12:58:21 -	LMT	1867 Oct 18
+			-11:01:38 -	LMT	1900 Aug 20 12:00
 			-11:00	-	NST	1942
 			-11:00	US	N%sT	1946
 			-11:00	-	NST	1967 Apr
 			-11:00	-	BST	1969
 			-11:00	US	B%sT	1983 Oct 30 2:00
 			 -9:00	US	AK%sT
-Zone America/Adak	-11:46:38 -	LMT	1900 Aug 20 12:00
+Zone America/Adak	 12:13:21 -	LMT	1867 Oct 18
+			-11:46:38 -	LMT	1900 Aug 20 12:00
 			-11:00	-	NST	1942
 			-11:00	US	N%sT	1946
 			-11:00	-	NST	1967 Apr
@@ -263,11 +351,6 @@ Zone Pacific/Honolulu	-10:31:26 -	LMT	1900 Jan  1 12:00
 			-10:30	US	H%sT	1947 Jun  8 2:00
 			-10:00	-	HST
 
-Zone Pacific/Midway	-11:49:28 -	LMT	1901
-			-11:00	-	NST	1967 Apr	# N=Nome
-			-11:00	-	BST	1983 Nov 30	# B=Bering
-			-11:00	-	SST			# S=Samoa
-
 # Now we turn to US areas that have diverged from the consensus since 1970.
 
 # Arizona mostly uses MST.
@@ -297,6 +380,11 @@ Zone America/Boise	-7:44:49 -	LMT	1883 Nov 18 12:00
 
 # Indiana
 #
+# For a map of Indiana's time zone regions, see:
+# <a href="http://www.mccsc.edu/time.html">
+# What time is it in Indiana?
+# </a> (1999-04-06)
+#
 # From Paul Eggert (1995-12-19):
 # Indiana generally observes either EST all year, or CST/CDT,
 # but areas near Cincinnati and Louisville use those cities' timekeeping
@@ -316,6 +404,13 @@ Zone America/Boise	-7:44:49 -	LMT	1883 Nov 18 12:00
 # So we reluctantly put them all in a subdirectory `America/Indiana'.
 #
 # Most of EST-only Indiana last observed DST in 1970.
+
+# From Paul Eggert (2001-03-06), following a tip by Markus Kuhn:
+# Pam Belluck reported in the New York Times (2001-01-31) that the
+# Indiana Legislature is considering a bill to adopt DST statewide.
+# Her article mentioned Vevay, whose post office observes a different
+# time zone than Danner's Hardware across the street.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
 Rule Indianapolis 1941	only	-	Jun	22	2:00	1:00	D
 Rule Indianapolis 1941	1954	-	Sep	lastSun	2:00	0	S
@@ -378,6 +473,7 @@ Zone America/Indiana/Vevay -5:40:16 -	LMT	1883 Nov 18 12:00
 			-5:00	-	EST
 
 # Part of Kentucky left its clocks alone in 1974.
+# This also includes a part of Indiana immediately adjacent to Louisville.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
 Rule Louisville	1921	only	-	May	1	2:00	1:00	D
 Rule Louisville	1921	only	-	Sep	1	2:00	0	S
@@ -396,15 +492,59 @@ Zone America/Louisville	-5:43:02 -	LMT	1883 Nov 18 12:00
 			-5:00	US	E%sT	1974 Jan  6 2:00
 			-6:00	1:00	CDT	1974 Oct 27 2:00
 			-5:00	US	E%sT
+Link America/Louisville America/Kentucky/Louisville
+#
+# Wayne, Clinton, and Russell Counties, Kentucky
+#
+# From
+# <a href="http://www.lake-cumberland.com/life/archive/news990129time.shtml">
+# Lake Cumberland LIFE
+# </a> (1999-01-29) via WKYM-101.7:
+# Clinton County has joined Wayne County in asking the DoT to change from
+# the Central to the Eastern time zone....  The Wayne County government made
+# the same request in December.  And while Russell County officials have not
+# taken action, the majority of respondents to a poll conducted there in
+# August indicated they would like to change to "fast time" also.
+# The three Lake Cumberland counties are the farthest east of any U.S.
+# location in the Central time zone.
+#
+# From Rich Wales (2000-08-29):
+# After prolonged debate, and despite continuing deep differences of opinion,
+# Wayne County (central Kentucky) is switching from Central (-0600) to Eastern
+# (-0500) time.  They won't "fall back" this year.  See Sara Shipley,
+# The difference an hour makes, Nando Times (2000-08-29 15:33 -0400).
+Zone America/Kentucky/Monticello -5:39:24 - LMT	1883 Nov 18 12:00
+			-6:00	US	C%sT	1946
+			-6:00	-	CST	1968
+			-6:00	US	C%sT	2000 Oct 29  2:00
+			-5:00	US	E%sT
+
+
+# From Rives McDow (2000-08-30):
+# Here ... are all the changes in the US since 1985.
+# Kearny County, KS (put all of county on central;
+#	previously split between MST and CST) ... 1990-10
+# Starke County, IN (from CST to EST) ... 1991-10
+# Oliver County, ND (from MST to CST) ... 1992-10
+# West Wendover, NV (from PST TO MST) ... 1999-10
+# Wayne County, KY (from CST to EST) ... 2000-10
+# There is another change in the offing; Mercer County, ND is looking
+# to change from MT to CT. It is possible that two other ND counties
+# (Sioux and Morton) will look to change also.  If made, the earliest
+# a change would be effective is October 2001.
+#
+# From Paul Eggert (2000-10-02):
+# FIXME: I haven't yet had time to incorporate all the above changes.
 
 # Michigan
 #
 # From Bob Devine (1988-01-28):
 # Michigan didn't observe DST from 1968 to 1973.
 #
-# From Paul Eggert (1995-12-19):
-# Shanks writes that Michigan started using standard time on 1885 Sep 18,
-# but Howse (p 126) writes that Detroit kept
+# From Paul Eggert (1999-03-31):
+# Shanks writes that Michigan started using standard time on 1885-09-18,
+# but Howse writes (pp 124-125, referring to Popular Astronomy, 1901-01)
+# that Detroit kept
 #
 #	local time until 1900 when the City Council decreed that clocks should
 #	be put back twenty-eight minutes to Central Standard Time.  Half the
@@ -416,6 +556,11 @@ Zone America/Louisville	-5:43:02 -	LMT	1883 Nov 18 12:00
 #
 # This story is too entertaining to be false, so go with Howse over Shanks.
 #
+# From Paul Eggert (2001-03-06):
+# Garland (1927) writes ``Cleveland and Detroit advanced their clocks
+# one hour in 1914.''  This change is not in Shanks.  We have no more
+# info, so omit this for now.
+#
 # Most of Michigan observed DST from 1973 on, but was a bit late in 1975.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
 Rule	Detroit	1948	only	-	Apr	lastSun	2:00	1:00	D
@@ -446,8 +591,14 @@ Zone America/Menominee	-5:50:27 -	LMT	1885 Sep 18 12:00
 			-6:00	US	C%sT
 
 # Navassa
-# uninhabited
-
+# claimed by US under the provisions of the 1856 Guano Islands Act
+# also claimed by Haiti
+# occupied 1857/1900 by the Navassa Phosphate Co
+# US lighthouse 1917/1997-01
+# currently uninhabited
+# see Mark Fineman, ``An Isle Rich in Guano and Discord'',
+# _Los Angeles Times_ (1998-11-10), A1, A10; it cites
+# Jimmy Skaggs, _The Great Guano Rush_ (1994).
 
 # Old names, for S5 users
 
@@ -463,12 +614,12 @@ Link	Pacific/Honolulu	HST
 ################################################################################
 
 
-# From Paul Eggert <eggert@twinsun.com> (1996-11-22):
+# From Paul Eggert <eggert@twinsun.com> (1999-10-29):
 # A good source for time zone historical data outside the US is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
+# Thomas G. Shanks, The International Atlas (5th edition),
+# San Diego: ACS Publications, Inc. (1999).
 #
-# Gwillim Law <LAW@encmail.encompass.com> writes that a good source
+# Gwillim Law <Gwil_Law@bridge-point.com> writes that a good source
 # for recent time zone data is the International Air Transport
 # Association's Standard Schedules Information Manual (IATA SSIM),
 # published semiannually.  Law sent in several helpful summaries
@@ -482,8 +633,6 @@ Link	Pacific/Honolulu	HST
 # I found in the UCLA library.
 #
 # See the `europe' file for Greenland.
-#
-# See the `africa' file for time zone naming and abbreviation conventions.
 
 # Canada
 
@@ -519,20 +668,38 @@ Link	Pacific/Honolulu	HST
 # From Paul Eggert <eggert@twinsun.com> (1994-11-22):
 # Alas, this sort of thing must be handled by localization software.
 
-# The data for Canada are all from Shanks (1991).
+# Unless otherwise specified, the data for Canada are all from Shanks.
 
+# From Paul Eggert (2000-10-02):
+# H. David Matthews and Mary Vincent's map
+# <a href="http://www.canadiangeographic.ca/SO98/geomap.htm">
+# "It's about TIME", _Canadian Geographic_ (September-October 1998)
+# </a> contains detailed boundaries for regions observing nonstandard
+# time and daylight saving time arrangements in Canada circa 1998.
+#
+# INMS, the Institute for National Measurement Standards in Ottawa, has
+# <a href="http://www.nrc.ca/inms/time/tze.html">
+# information about standard and daylight saving time zones in Canada.
+# </a> (updated periodically).
+# Its unofficial information is often taken from Matthews and Vincent.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Canada	1918	only	-	Apr	14	2:00	1:00	D
 Rule	Canada	1918	only	-	Oct	31	2:00	0	S
-Rule	Canada	1942	only	-	Feb	 9	2:00	1:00	D
+Rule	Canada	1942	only	-	Feb	 9	2:00	1:00	W
 Rule	Canada	1945	only	-	Sep	30	2:00	0	S
 Rule	Canada	1974	1986	-	Apr	lastSun	2:00	1:00	D
 Rule	Canada	1974	max	-	Oct	lastSun	2:00	0	S
 Rule	Canada	1987	max	-	Apr	Sun>=1	2:00	1:00	D
 
 
-# Newfoundland (except Labrador)
+# Newfoundland (and far southeast Labrador)
+
+# From Paul Eggert (2000-10-02):
+# Matthews and Vincent (1998) write that Labrador should use NST/NDT,
+# but the only part of Labrador that follows the rules is the
+# southeast corner, including Port Hope Simpson and Mary's Harbour,
+# but excluding, say, Black Tickle.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	StJohns	1917	1918	-	Apr	Sun>=8	2:00	1:00	D
@@ -548,13 +715,13 @@ Rule	StJohns	1920	1935	-	Oct	lastSun	23:00	0	S
 Rule	StJohns	1936	1941	-	May	Sun>=8	0:00	1:00	D
 Rule	StJohns	1936	1941	-	Oct	Sun>=1	0:00	0	S
 # Shanks gives 1942 May 11 - 1945 Sep 30; go with Whitman.
-Rule	StJohns	1942	only	-	Mar	 1	0:00	1:00	D
+Rule	StJohns	1942	only	-	Mar	 1	0:00	1:00	W
 Rule	StJohns	1942	only	-	Dec	31	0:00	0	S
-Rule	StJohns	1943	only	-	May	30	0:00	1:00	D
+Rule	StJohns	1943	only	-	May	30	0:00	1:00	W
 Rule	StJohns	1943	only	-	Sep	 5	0:00	0	S
-Rule	StJohns	1944	only	-	Jul	10	0:00	1:00	D
+Rule	StJohns	1944	only	-	Jul	10	0:00	1:00	W
 Rule	StJohns	1944	only	-	Sep	 2	0:00	0	S
-Rule	StJohns	1945	only	-	Jan	 1	0:00	1:00	D
+Rule	StJohns	1945	only	-	Jan	 1	0:00	1:00	W
 Rule	StJohns	1945	only	-	Oct	 7	2:00	0	S
 # For 1946-9 Whitman gives May 5,4,9,1 - Oct 1,5,3,2, and for 1950 he gives
 # Apr 30 - Sep 24; go with Shanks.
@@ -562,10 +729,14 @@ Rule	StJohns	1946	1950	-	May	Sun>=8	2:00	1:00	D
 Rule	StJohns	1946	1950	-	Oct	Sun>=2	2:00	0	S
 Rule	StJohns	1951	1986	-	Apr	lastSun	2:00	1:00	D
 Rule	StJohns	1951	1959	-	Sep	lastSun	2:00	0	S
-Rule	StJohns	1960	max	-	Oct	lastSun	2:00	0	S
-Rule	StJohns	1987	only	-	Apr	Sun>=1	2:00	1:00	D
-Rule	StJohns	1988	only	-	Apr	Sun>=1	2:00	2:00	DD
-Rule	StJohns	1989	max	-	Apr	Sun>=1	2:00	1:00	D
+Rule	StJohns	1960	1986	-	Oct	lastSun	2:00	0	S
+# From Paul Eggert (2000-10-02):
+# INMS (2000-09-12) says that, since 1988 at least, Newfoundland switches
+# at 00:01 local time.  For now, assume it started in 1987.
+Rule	StJohns	1987	only	-	Apr	Sun>=1	0:01	1:00	D
+Rule	StJohns	1987	max	-	Oct	lastSun	0:01	0	S
+Rule	StJohns	1988	only	-	Apr	Sun>=1	0:01	2:00	DD
+Rule	StJohns	1989	max	-	Apr	Sun>=1	0:01	1:00	D
 # St John's has an apostrophe, but Posix file names can't have apostrophes.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/St_Johns	-3:30:52 -	LMT	1884
@@ -573,7 +744,7 @@ Zone America/St_Johns	-3:30:52 -	LMT	1884
 			-3:30	StJohns	N%sT
 
 
-# east Labrador
+# most of east Labrador
 
 # The name `Happy Valley-Goose Bay' is too long; use `Goose Bay'.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -594,6 +765,11 @@ Zone America/Goose_Bay	-4:01:40 -	LMT	1884 # Happy Valley-Goose Bay
 # Shanks also writes that Liverpool, NS was the only town in Canada to observe
 # DST in 1971 but not 1970; for now we'll assume this is a typo.
 
+# From Paul Eggert (2000-10-02):
+# INMS (2000-09-12) says that, since 1988 at least, New Brunswick switches
+# at 00:01 local time.  FIXME: verify and create a new Zone for this.
+
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule Halifax	1916	only	-	Apr	 1	0:00	1:00	D
 Rule Halifax	1916	only	-	Oct	 1	0:00	0	S
@@ -629,7 +805,7 @@ Rule Halifax	1937	1938	-	May	Sun>=1	0:00	1:00	D
 Rule Halifax	1937	1941	-	Sep	Mon>=24	0:00	0	S
 Rule Halifax	1939	only	-	May	28	0:00	1:00	D
 Rule Halifax	1940	1941	-	May	Sun>=1	0:00	1:00	D
-Rule Halifax	1942	only	-	Feb	9	2:00	1:00	D
+Rule Halifax	1942	only	-	Feb	9	2:00	1:00	W
 Rule Halifax	1945	1959	-	Sep	lastSun	2:00	0	S
 Rule Halifax	1946	1959	-	Apr	lastSun	2:00	1:00	D
 Rule Halifax	1962	1986	-	Apr	lastSun	2:00	1:00	D
@@ -654,6 +830,31 @@ Zone America/Glace_Bay	-3:59:48 -	LMT	1902 Jun 15
 # Nipigon (EST) and Rainy River (CST) are the largest that we know of.
 # Far west Ontario is like Winnipeg; far east Quebec is like Halifax.
 
+# From Paul Eggert (1997-10-17):
+# msb@sq.com writes that an article in the 1997-10-14 Toronto Star
+# says that Atikokan, Ontario currently does not observe DST,
+# but will vote on 11-10 whether to use EST/EDT.
+# He also writes that the
+# <a href="http://www.gov.on.ca/MBS/english/publications/statregs/conttext.html">
+# Ontario Time Act (1990, Chapter T.9)
+# </a>
+# says that Ontario east of 90W uses EST/EDT, and west of 90W uses CST/CDT.
+# Officially Atikokan is therefore on CST/CDT, and most likely this report
+# concerns a non-official time observed as a matter of local practice.
+# For what it's worth, Shanks says that Atikokan has agreed with
+# Rainy River ever since standard time was introduced.
+
+# From Paul Eggert (2000-10-02):
+# Matthews and Vincent (1998) write that Atikokan, Pickle Lake, and
+# New Osnaburgh observe CST all year, that Big Trout Lake observes
+# CST/CDT, and that Upsala and Shebandowan observe EST/EDT, all in
+# violation of the official Ontario rules.
+# They also write that Quebec east of the -63 meridian is supposed to
+# observe AST, but residents as far east as Natashquan use EST/EDT,
+# and residents east of Natashquan use AST.
+# We probably need Zones for far east Quebec and for Atikokan,
+# but we don't know when their practices started.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Mont	1917	only	-	Mar	25	2:00	1:00	D
 Rule	Mont	1917	only	-	Apr	24	0:00	0	S
@@ -706,7 +907,7 @@ Rule	Winn	1918	only	-	Apr	14	2:00	1:00	D
 Rule	Winn	1918	only	-	Oct	31	2:00	0	S
 Rule	Winn	1937	only	-	May	16	2:00	1:00	D
 Rule	Winn	1937	only	-	Sep	26	2:00	0	S
-Rule	Winn	1942	only	-	Feb	 9	2:00	1:00	D
+Rule	Winn	1942	only	-	Feb	 9	2:00	1:00	W
 Rule	Winn	1945	only	-	Sep	lastSun	2:00	0	S
 Rule	Winn	1946	only	-	May	12	2:00	1:00	D
 Rule	Winn	1946	only	-	Oct	13	2:00	0	S
@@ -721,8 +922,12 @@ Rule	Winn	1960	only	-	Sep	lastSun	2:00	0	S
 Rule	Winn	1963	only	-	Apr	lastSun	2:00	1:00	D
 Rule	Winn	1963	only	-	Sep	22	2:00	0	S
 Rule	Winn	1966	1986	-	Apr	lastSun	2:00	1:00	D
-Rule	Winn	1966	max	-	Oct	lastSun	2:00	0	S
+Rule	Winn	1966	1986	-	Oct	lastSun	2:00	0	S
 Rule	Winn	1987	max	-	Apr	Sun>=1	2:00	1:00	D
+# From Paul Eggert (2000-10-02):
+# INMS (2000-09-12) says that, since 1988 at least, Manitoba switches from
+# DST at 03:00 local time.  For now, assume it started in 1987.
+Rule	Winn	1987	max	-	Oct	lastSun	2:00s	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Winnipeg	-6:28:36 -	LMT	1887 Jul 16
 			-6:00	Winn	C%sT
@@ -730,10 +935,12 @@ Zone America/Winnipeg	-6:28:36 -	LMT	1887 Jul 16
 
 # Saskatchewan
 
-# From Paul Eggert (1996-06-12):
+# From Paul Eggert (2000-10-02):
 # Shanks writes that since 1970 most of this region has been like Regina.
 # Some western towns (e.g. Swift Current) switched from MST/MDT to CST in 1972.
 # Other western towns (e.g. Lloydminster) are like Edmonton.
+# Matthews and Vincent (1998) write that Denare Beach and Creighton
+# are like Winnipeg, in violation of Saskatchewan law.
 
 # From W. Jones <jones@skdad.usask.ca> (1992-11-06):
 # The. . .below is based on information I got from our law library, the
@@ -770,7 +977,7 @@ Rule	Regina	1937	1941	-	Apr	Sun>=8	0:00	1:00	D
 Rule	Regina	1937	only	-	Oct	Sun>=8	0:00	0	S
 Rule	Regina	1938	only	-	Oct	Sun>=1	0:00	0	S
 Rule	Regina	1939	1941	-	Oct	Sun>=8	0:00	0	S
-Rule	Regina	1942	only	-	Feb	 9	2:00	1:00	D
+Rule	Regina	1942	only	-	Feb	 9	2:00	1:00	W
 Rule	Regina	1945	only	-	Sep	lastSun	2:00	0	S
 Rule	Regina	1946	only	-	Apr	Sun>=8	2:00	1:00	D
 Rule	Regina	1946	only	-	Oct	Sun>=8	2:00	0	S
@@ -803,7 +1010,7 @@ Rule	Edm	1919	only	-	May	27	2:00	0	S
 Rule	Edm	1920	1923	-	Apr	lastSun	2:00	1:00	D
 Rule	Edm	1920	only	-	Oct	lastSun	2:00	0	S
 Rule	Edm	1921	1923	-	Sep	lastSun	2:00	0	S
-Rule	Edm	1942	only	-	Feb	 9	2:00	1:00	D
+Rule	Edm	1942	only	-	Feb	 9	2:00	1:00	W
 Rule	Edm	1945	only	-	Sep	lastSun	2:00	0	S
 Rule	Edm	1947	only	-	Apr	lastSun	2:00	1:00	D
 Rule	Edm	1947	only	-	Sep	lastSun	2:00	0	S
@@ -821,14 +1028,15 @@ Zone America/Edmonton	-7:33:52 -	LMT	1906 Sep
 
 # British Columbia
 
-# From Paul Eggert (1996-06-12):
+# From Paul Eggert (2000-10-02):
 # Shanks writes that since 1970 most of this region has been like Vancouver.
-# Dawswon Creek uses MST.  Much of east BC is like Edmonton.
+# Dawson Creek uses MST.  Much of east BC is like Edmonton.
+# Matthews and Vincent (1998) write that Creston is like Dawson Creek.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Vanc	1918	only	-	Apr	14	2:00	1:00	D
 Rule	Vanc	1918	only	-	Oct	31	2:00	0	S
-Rule	Vanc	1942	only	-	Feb	 9	2:00	1:00	D
+Rule	Vanc	1942	only	-	Feb	 9	2:00	1:00	W
 Rule	Vanc	1945	only	-	Sep	30	2:00	0	S
 Rule	Vanc	1946	1986	-	Apr	lastSun	2:00	1:00	D
 Rule	Vanc	1946	only	-	Oct	13	2:00	0	S
@@ -844,11 +1052,10 @@ Zone America/Dawson_Creek -8:00:56 -	LMT	1884
 			-7:00	-	MST
 
 
-# Northwest Territories, Yukon
+# Northwest Territories, Nunavut, Yukon
 
-# From Paul Eggert (1996-10-07):
+# From Paul Eggert (1999-10-29):
 # Dawson switched to PST in 1973.  Inuvik switched to MST in 1979.
-# Shanks's table for Watson Lake is corrupted, so we have no data there.
 # Mathew Englander <mathew@io.org> (1996-10-07) gives the following refs:
 #	* 1967. Paragraph 28(34)(g) of the Interpretation Act, S.C. 1967-68,
 #	c. 7 defines Yukon standard time as UTC-9.  This is still valid;
@@ -858,12 +1065,104 @@ Zone America/Dawson_Creek -8:00:56 -	LMT	1884
 #	* O.I.C. 1987/056 changed DST to Apr firstSun 2:00 to Oct lastSun 2:00.
 # Shanks says Yukon's 1973-10-28 switch was at 2:00; go with Englander.
 
+# From Rives McDow (1999-09-04):
+# Nunavut ... moved ... to incorporate the whole territory into one time zone.
+# <a href="http://www.nunatsiaq.com/nunavut/nvt90903_13.html">
+# Nunavut moves to single time zone Oct. 31
+# </a>
+#
+# From Antoine Leca (1999-09-06):
+# We then need to create a new timezone for the Kitikmeot region of Nunavut
+# to differentiate it from the Yellowknife region.
+
+# From Paul Eggert (1999-09-20):
+# <a href="http://www.nunavut.com/basicfacts/english/basicfacts_1territory.html">
+# Basic Facts: The New Territory
+# </a> (1999) reports that Pangnirtung operates on Eastern time,
+# and that Coral Harbour does not observe DST.  We don't know when
+# Pangnirtung switched to Eastern time; we'll guess 1995.
+# We'll ignore the claim about Coral Harbour for now,
+# since we have no further info.
+
+# From Rives McDow (1999-11-08):
+# On October 31, when the rest of Nunavut went to Central time,
+# Pangnirtung wobbled.  Here is the result of their wobble:
+#
+# The following businesses and organizations in Pangnirtung use Central Time:
+#
+#	First Air, Power Corp, Nunavut Construction, Health Center, RCMP,
+#	Eastern Arctic National Parks, A & D Specialist
+#
+# The following businesses and organizations in Pangnirtung use Eastern Time:
+#
+#	Hamlet office, All other businesses, Both schools, Airport operator
+#
+# This has made for an interesting situation there, which warranted the news.
+# No one there that I spoke with seems concerned, or has plans to
+# change the local methods of keeping time, as it evidently does not
+# really interfere with any activities or make things difficult locally.
+# They plan to celebrate New Year's turn-over twice, one hour apart,
+# so it appears that the situation will last at least that long.
+# The Nunavut Intergovernmental Affairs hopes that they will "come to
+# their senses", but the locals evidently don't see any problem with
+# the current state of affairs.
+
+# From Michaela Rodrigue, writing in the
+# <a href="http://www.nunatsiaq.com/archives/nunavut991130/nvt91119_17.html">
+# Nunatsiaq News (1999-11-19)</a>:
+# Clyde River, Pangnirtung and Sanikiluaq now operate with two time zones,
+# central - or Nunavut time - for government offices, and eastern time
+# for municipal offices and schools....  Igloolik [was similar but then]
+# made the switch to central time on Saturday, Nov. 6.
+
+# From Paul Eggert (2000-10-02):
+# Matthews and Vincent (1998) say the following, but we lack histories
+# for these potential new Zones.
+#
+# The Canadian Forces station at Alert uses Eastern Time while the
+# handful of residents at the Eureka weather station [in the Central
+# zone] skip daylight savings.  Baffin Island, which is crossed by the
+# Central, Eastern and Atlantic Time zones only uses Eastern Time.
+# Gjoa Haven, Taloyoak and Pelly Bay all use Mountain instead of
+# Central Time and Southampton Island [in the Central zone] is not
+# required to use daylight savings.
+
+# From
+# <a href="http://www.nunatsiaq.com/archives/nunavut001130/nvt21110_02.html">
+# Nunavut now has two time zones
+# </a> (2000-11-10):
+# The Nunavut government would allow its employees in Kugluktuk and
+# Cambridge Bay to operate on central time year-round, putting them
+# one hour behind the rest of Nunavut for six months during the winter.
+# At the end of October the two communities had rebelled against
+# Nunavut's unified time zone, refusing to shift to eastern time with
+# the rest of the territory for the winter.  Cambridge Bay remained on
+# central time, while Kugluktuk, even farther west, reverted to
+# mountain time, which they had used before the advent of Nunavut's
+# unified time zone in 1999.
+#
+# From Rives McDow (2001-01-20), quoting the Nunavut government:
+# The preceding decision came into effect at midnight, Saturday Nov 4, 2000.
+
+# From Paul Eggert (2000-12-04):
+# Let's just keep track of the official times for now.
+
+# From Rives McDow (2001-03-07):
+# The premier of Nunavut has issued a ministerial statement advising
+# that effective 2001-04-01, the territory of Nunavut will revert
+# back to three time zones (mountain, central, and eastern).  Of the
+# cities in Nunavut, Coral Harbor is the only one that I know of that
+# has said it will not observe dst, staying on EST year round.  I'm
+# checking for more info, and will get back to you if I come up with
+# more.
+# [Also see <http://www.nunatsiaq.com/nunavut/nvt10309_06.html> (2001-03-09).]
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	NT_YK	1918	only	-	Apr	14	2:00	1:00	D
 Rule	NT_YK	1918	only	-	Oct	27	2:00	0	S
 Rule	NT_YK	1919	only	-	May	25	2:00	1:00	D
 Rule	NT_YK	1919	only	-	Nov	 1	0:00	0	S
-Rule	NT_YK	1942	only	-	Feb	 9	2:00	1:00	D
+Rule	NT_YK	1942	only	-	Feb	 9	2:00	1:00	W
 Rule	NT_YK	1945	only	-	Sep	30	2:00	0	S
 Rule	NT_YK	1965	only	-	Apr	lastSun	0:00	2:00	DD
 Rule	NT_YK	1965	only	-	Oct	lastSun	2:00	0	S
@@ -872,11 +1171,24 @@ Rule	NT_YK	1980	max	-	Oct	lastSun	2:00	0	S
 Rule	NT_YK	1987	max	-	Apr	Sun>=1	2:00	1:00	D
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Pangnirtung -4:22:56 -	LMT	1884
-			-4:00	NT_YK	A%sT
-Zone America/Iqaluit	-4:33:52 -	LMT	1884	# Frobisher Bay
-			-5:00	NT_YK	E%sT
+			-4:00	NT_YK	A%sT	1995 Apr Sun>=1 2:00
+			-5:00	Canada	E%sT	1999 Oct 31 2:00
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
+			-5:00	Canada	E%sT
+Zone America/Iqaluit	-4:33:52 -	LMT	1884 # Frobisher Bay before 1987
+			-5:00	NT_YK	E%sT	1999 Oct 31 2:00
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
+			-5:00	Canada	E%sT
 Zone America/Rankin_Inlet -6:08:40 -	LMT	1884
-			-6:00	NT_YK	C%sT
+			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
+			-5:00	-	EST	2001 Apr  1 3:00
+			-6:00	Canada	C%sT
+Zone America/Cambridge_Bay -7:00:20 -	LMT	1884
+			-7:00	NT_YK	M%sT	1999 Oct 31 2:00
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
+			-5:00	-	EST	2000 Nov  5 0:00
+			-6:00	-	CST	2001 Apr  1 3:00
+			-7:00	Canada	M%sT
 Zone America/Yellowknife -7:37:24 -	LMT	1884
 			-7:00	NT_YK	M%sT
 Zone America/Inuvik	-8:54:00 -	LMT	1884
@@ -894,139 +1206,233 @@ Zone America/Dawson	-9:17:40 -	LMT	1900 Aug 20
 
 # Mexico
 
-# From Guy Harris:
-# Rules are from the Official Airline Guide, Worldwide Edition, for 1987.
-# Rules prior to 1987 are unknown.
-# The comments in the OAG say "Only Ensenada, Mexicale, San Felipe and Tijuana
-# observe DST."  This is presumably Baja California Norte, above 28th parallel,
-# as listed there; [there is also] "Baja California Sur and N. Pacific
-# Coast (States of Sinaloa and Sonora)."
-
-# From Bob Devine (1988-01-28):
-# The Federal District (where Mexico City is) has observed [DST] several
-# times but not recently.
-#
-# I don't where to drawn the line in the North Baja area.  28th latitude
-# sounds good -- but it may be higher (how far [d]o radio stations from
-# San Diego affect culture?).
+# From Paul Eggert (2001-03-05):
+# The Investigation and Analysis Service of the
+# Mexican Library of Congress (MLoC) has published a
+# <a href="http://www.cddhcu.gob.mx/bibliot/publica/inveyana/polisoc/horver/">
+# history of Mexican local time (in Spanish)
+# </a>.
 #
-# The dates of DST probably go back to 1981.  The rules are the same as
-# US's.  This is going to be a headache for US presidential electi[o]n years!
-
-# From Arthur David Olson (1988-02-13)
-# Since the 1981 starting date is only "probable," we'll keep the 1987
-# starting date below.
-
-# From U. S. Naval Observatory (1989-01-19):
-# MEXICO BAJA CAL N   7 H  BEHIND UTC    BAJA CALIFORNIA SUR AND
-# MEXICO BAJA CAL N                      N. PACIFIC COAST (STATES
-# MEXICO BAJA CAL N                      OF SINALOA AND SONORA)
-# MEXICO BAJA CAL N   8 H  BEHIND UTC    ABOVE 28TH PARALLEL APR 3
-# MEXICO BAJA CAL N                      - OCT 29
-# MEXICO BAJA CAL N   7 H  BEHIND UTC    ABOVE 28TH PARALLEL APR 3
-# MEXICO BAJA CAL N                      - 0CT 29
-# MEXICO              6 H  BEHIND UTC    STATES OF DURANGO,
-# MEXICO                                 COAHUILA, NUEVO LEON,
-# MEXICO                                 TAMAULIPAS
-# MEXICO              5 H  BEHIND UTC    STATES OF DURANGO,
-# MEXICO                                 COAHUILA, NUEVO LEON,
-# MEXICO                                 TAMAULIPAS  APR 3 - OCT 29
-# MEXICO              6 H  BEHIND UTC    GENERAL MEXICO, STATES OF
-# MEXICO                                 CAMPECHE, QUINTANA ROO AND
-# MEXICO                                 YUCATAN
-
-# From Arthur David Olson (1989-01-21):
-# April 3 fell on a Sunday in 1988; October 29 fell on a Sunday in 1989.  Ahem.
-# USNO claims there should be four Mexican zones rather than three:
-# a zone that's GMT-8 with DST; a zone that's always GMT-7;
-# a zone that's GMT-6 with DST; and a zone that's always GMT-6.
-
-# From Paul Eggert <eggert@twinsun.com> (1993-11-18):
-# Shanks also says there are four zones, but disagrees about the fourth.
-# Instead of GMT-6 with DST, he says there's GMT-8 without DST.
+# Here are the discrepancies between Shanks and the MLoC.
+# (In all cases we go with the MLoC.)
+# Shanks reports that Baja was at -8:00 in 1922/1923.
+# Shanks says the 1930 transition in Baja was 1930-11-16.
+# Shanks reports no DST during summer 1931.
+# Shanks reports a transition at 1032-03-30 23:00, not 1932-04-01.
+# Shanks does not report transitions for Baja in 1945 or 1948.
+# Shanks reports southern Mexico transitions on 1981-12-01, not 12-23.
+# Shanks says Quintana Roo switched to -6:00 on 1982-12-02, and to -5:00
+# on 1997-10-26 at 02:00.
+
+# From Gwillim Law (2001-02-20):
+# There are some other discrepancies between the Decrees page and the
+# tz database.  I think they can best be explained by supposing that
+# the researchers who prepared the Decrees page failed to find some of
+# the relevant documents.
+
+# From Paul Eggert (2000-07-26):
+# Shanks gives 1942-04-01 instead of 1942-04-24, and omits the 1981
+# and 1988 DST experiments.  Go with spin.com.mx.
 
 # From Alan Perry <alan.perry@eng.sun.com> (1996-02-15):
 # A guy from our Mexico subsidiary finally found the Presidential Decree
 # outlining the timezone changes in Mexico.
-# 
+#
 # ------------- Begin Forwarded Message -------------
-# 
+#
 # I finally got my hands on the Official Presidential Decree that sets up the
 # rules for the DST changes. The rules are:
-# 
+#
 # 1. The country is divided in 3 timezones:
 #    - Baja California Norte (the Mexico/BajaNorte TZ)
 #    - Baja California Sur, Nayarit, Sinaloa and Sonora (the Mexico/BajaSur TZ)
 #    - The rest of the country (the Mexico/General TZ)
-#    
+#
 # 2. From the first Sunday in April at 2:00 AM to the last Sunday in October
 #    at 2:00 AM, the times in each zone are as follows:
 #    BajaNorte: GMT+7
 #    BajaSur:   GMT+6
 #    General:   GMT+5
-#    
+#
 # 3. The rest of the year, the times are as follows:
 #    BajaNorte: GMT+8
 #    BajaSur:   GMT+7
 #    General:   GMT+6
-#    
+#
 # The Decree was published in Mexico's Official Newspaper on January 4th.
-# 
+#
 # -------------- End Forwarded Message --------------
 # From Paul Eggert (1996-06-12):
-# For an English translation of the decree,
-# see ``Diario Oficial: Time Zone Changeover'',
-# <URL:http://mexico-travel.com/extra/timezone_eng.html> (1996-01-04).
+# For an English translation of the decree, see
+# <a href="http://mexico-travel.com/extra/timezone_eng.html">
+# ``Diario Oficial: Time Zone Changeover'' (1996-01-04).
+# </a>
+
+# From Rives McDow (1998-10-08):
+# The State of Quintana Roo has reverted back to central STD and DST times
+# (i.e. UTC -0600 and -0500 as of 1998-08-02).
+
+# From Rives McDow (2000-01-10):
+# Effective April 4, 1999 at 2:00 AM local time, Sonora changed to the time
+# zone 5 hours from the International Date Line, and will not observe daylight
+# savings time so as to stay on the same time zone as the southern part of
+# Arizona year round.
+
+# From Jesper Norgaard, translating
+# <http://www.reforma.com/nacional/articulo/064327/> (2001-01-17):
+# In Oaxaca, the 55.000 teachers from the Section 22 of the National
+# Syndicate of Education Workers, refuse to apply daylight saving each
+# year, so that the more than 10,000 schools work at normal hour the
+# whole year.
+
+# From Gwillim Law (2001-01-19):
+# <http://www.reforma.com/negocios_y_dinero/articulo/064481/> ... says
+# (translated):...
+# January 17, 2000 - The Energy Secretary, Ernesto Martens, announced
+# that Summer Time will be reduced from seven to five months, starting
+# this year....
+# <http://www.publico.com.mx/scripts/texto3.asp?action=pagina&pag=21&pos=p&secc=naci&date=01/17/2001>
+# [translated], says "summer time will ... take effect on the first Sunday
+# in May, and end on the last Sunday of September.
+
+# From Arthur David Olson (2001-01-25):
+# The 2001-01-24 traditional Washington Post contained the page one
+# story "Timely Issue Divides Mexicans."...
+# http://www.washingtonpost.com/wp-dyn/articles/A37383-2001Jan23.html
+# ... Mexico City Mayor Lopez Obrador "...is threatening to keep
+# Mexico City and its 20 million residents on a different time than
+# the rest of the country..." In particular, Lopez Obrador would abolish
+# observation of Daylight Saving Time.
+
+# <a href="http://www.conae.gob.mx/ahorro/decretohorver2001.html#decre">
+# Official statute published by the Energy Department
+# </a> (2001-02-01) shows Baja and Chihauhua as still using US DST rules,
+# and Sonora with no DST.  This was reported by Jesper Norgaard (2001-02-03).
+
+# From Paul Eggert (2001-03-03):
+#
+# <a href="http://www.latimes.com/news/nation/20010303/t000018766.html">
+# James F. Smith writes in today's LA Times
+# </a>
+# * Sonora will continue to observe standard time.
+# * Last week Mexico City's mayor Andres Manuel Lopez Obrador decreed that
+#   the Federal District will not adopt DST.
+# * 4 of 16 district leaders announced they'll ignore the decree.
+# * The decree does not affect federal-controlled facilities including
+#   the airport, banks, hospitals, and schools.
+#
+# For now we'll assume that the Federal District will bow to federal rules.
+
+# From Jesper Norgaard (2001-04-01):
+# I found some references to the Mexican application of daylight
+# saving, which modifies what I had already sent you, stating earlier
+# that a number of northern Mexican states would go on daylight
+# saving. The modification reverts this to only cover Baja California
+# (Norte), while all other states (except Sonora, who has no daylight
+# saving all year) will follow the original decree of president
+# Vicente Fox, starting daylight saving May 6, 2001 and ending
+# September 30, 2001.
+# References: "Diario de Monterrey" <www.diariodemonterrey.com/index.asp>
+# Palabra <http://palabra.infosel.com/010331/primera/ppri3101.pdf> (2001-03-31)
 
-# From Shanks (1991):
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Mexico	1939	only	-	Feb	5	0:00	1:00	D
 Rule	Mexico	1939	only	-	Jun	25	0:00	0	S
 Rule	Mexico	1940	only	-	Dec	9	0:00	1:00	D
 Rule	Mexico	1941	only	-	Apr	1	0:00	0	S
-Rule	Mexico	1943	only	-	Dec	16	0:00	1:00	D
+Rule	Mexico	1943	only	-	Dec	16	0:00	1:00	W
 Rule	Mexico	1944	only	-	May	1	0:00	0	S
 Rule	Mexico	1950	only	-	Feb	12	0:00	1:00	D
 Rule	Mexico	1950	only	-	Jul	30	0:00	0	S
-Rule	Mexico	1996	max	-	Apr	Sun>=1	2:00	1:00	D
-Rule	Mexico	1996	max	-	Oct	lastSun	2:00	0	S
-#
-Rule	BajaN	1950	1966	-	Apr	lastSun	2:00	1:00	D
-Rule	BajaN	1950	1961	-	Sep	lastSun	2:00	0	S
-Rule	BajaN	1961	1966	-	Oct	lastSun	2:00	0	S
+Rule	Mexico	1996	2000	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Mexico	1996	2000	-	Oct	lastSun	2:00	0	S
+Rule	Mexico	2001	max	-	May	Sun>=1	2:00	1:00	D
+Rule	Mexico	2001	max	-	Sep	lastSun	2:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Quintana Roo
+Zone America/Cancun	-5:47:04 -	LMT	1922 Jan  1  0:12:56
+			-6:00	-	CST	1981 Dec 23
+			-5:00	Mexico	E%sT	1998 Aug  2  2:00
+			-6:00	Mexico	C%sT
+# Campeche, Yucatan
+Zone America/Merida	-5:58:28 -	LMT	1922 Jan  1  0:01:32
+			-6:00	-	CST	1981 Dec 23
+			-5:00	-	EST	1982 Dec  2
+			-6:00	Mexico	C%sT
+# Coahuila, Durango, Nuevo Leon, Tamaulipas
+Zone America/Monterrey	-6:41:16 -	LMT	1921 Dec 31 23:18:44
+			-6:00	-	CST	1988
+			-6:00	US	C%sT	1989
+			-6:00	Mexico	C%sT
+# Central Mexico
 Zone America/Mexico_City -6:36:36 -	LMT	1922 Jan  1  0:23:24
 			-7:00	-	MST	1927 Jun 10 23:00
 			-6:00	-	CST	1930 Nov 15
 			-7:00	-	MST	1931 May  1 23:00
 			-6:00	-	CST	1931 Oct
-			-7:00	-	MST	1932 Mar 30 23:00
+			-7:00	-	MST	1932 Apr  1
 			-6:00	Mexico	C%sT
+# Chihuahua
+Zone America/Chihuahua	-7:04:20 -	LMT	1921 Dec 31 23:55:40
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1996
+			-6:00	Mexico	C%sT	1998
+			-6:00	-	CST	1998 Apr Sun>=1 3:00
+			-7:00	Mexico	M%sT
+# Sonora
+Zone America/Hermosillo	-7:23:52 -	LMT	1921 Dec 31 23:36:08
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1942 Apr 24
+			-7:00	-	MST	1949 Jan 14
+			-8:00	-	PST	1970
+			-7:00	Mexico	M%sT	1999
+			-7:00	-	MST
+# Baja California Sur, Nayarit, Sinaloa
 Zone America/Mazatlan	-7:05:40 -	LMT	1921 Dec 31 23:54:20
 			-7:00	-	MST	1927 Jun 10 23:00
 			-6:00	-	CST	1930 Nov 15
 			-7:00	-	MST	1931 May  1 23:00
 			-6:00	-	CST	1931 Oct
-			-7:00	-	MST	1932 Mar 30 23:00
-			-6:00	-	CST	1942 Apr
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1942 Apr 24
 			-7:00	-	MST	1949 Jan 14
 			-8:00	-	PST	1970
 			-7:00	Mexico	M%sT
+# Baja California
 Zone America/Tijuana	-7:48:04 -	LMT	1922 Jan  1  0:11:56
+			-7:00	-	MST	1924
 			-8:00	-	PST	1927 Jun 10 23:00
-			-7:00	-	MST	1930 Nov 16
-			-8:00	-	PST	1942 Apr
-			-7:00	-	MST	1949 Jan 14
-			-8:00	BajaN	P%sT	1967 Apr lastSun 2:00
+			-7:00	-	MST	1930 Nov 15
+			-8:00	-	PST	1931 Apr  1
+			-8:00	1:00	PDT	1931 Sep 30
+			-8:00	-	PST	1942 Apr 24
+			-8:00	1:00	PWT	1945 Nov 12
+			-8:00	-	PST	1948 Apr  5
+			-8:00	1:00	PDT	1949 Jan 14
+			-8:00	-	PST	1954
+			-8:00	CA	P%sT	1961
+			-8:00	-	PST	1976
 			-8:00	US	P%sT	1996
-			-8:00	Mexico	P%sT
-Zone America/Ensenada	-7:46:28 -	LMT	1922 Jan  1  0:13:32
-			-8:00	-	PST	1927 Jun 10 23:00
-			-7:00	-	MST	1930 Nov 16
-			-8:00	-	PST	1942 Apr
-			-7:00	-	MST	1949 Jan 14
-			-8:00	-	PST	1996
-			-8:00	Mexico	P%sT
+			-8:00	Mexico	P%sT	2001
+			-8:00	US	P%sT
+# From Paul Eggert (2001-03-05):
+# Formerly there was an America/Ensenada zone, which differed from
+# America/Tijuana only in that it did not observe DST from 1976
+# through 1995.  This was as per Shanks.  However, Guy Harris reports
+# that the 1987 OAG says "Only Ensenada, Mexicale, San Felipe and
+# Tijuana observe DST," which contradicts Shanks but does imply that
+# DST-observance was a town-by-town matter back then.  This concerns
+# data after 1970 so most likely there should be at least one Zone
+# other than America/Tijuana for Baja, but it's not clear yet what its
+# name or contents should be.
 #
 # Revillagigedo Is
 # no information
@@ -1062,7 +1468,7 @@ Rule	Barb	1979	only	-	Sep	30	2:00	0	S
 Rule	Barb	1980	only	-	Sep	25	2:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Barbados	-3:58:28 -	LMT	1924		# Bridgetown
-			-3:58	-	BMT	1932	  # Bridgetown Mean Time
+			-3:58:28 -	BMT	1932	  # Bridgetown Mean Time
 			-4:00	Barb	A%sT
 
 # Belize
@@ -1087,15 +1493,10 @@ Zone Atlantic/Bermuda	-4:19:04 -	LMT	1930 Jan  1 2:00    # Hamilton
 # Cayman Is
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Cayman	-5:25:32 -	LMT	1890		# Georgetown
-			-5:07	-	KMT	1912 Feb    # Kingston Mean Time
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
 			-5:00	-	EST
 
-# Clipperton
-# uninhabited
-
 # Costa Rica
-# Shanks gives some very odd dates for 1991, and stops there.
-# For now, we won't guess further.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	CR	1979	1980	-	Feb	lastSun	0:00	1:00	D
 Rule	CR	1979	1980	-	Jun	Sun>=1	0:00	0	S
@@ -1106,23 +1507,24 @@ Rule	CR	1992	only	-	Mar	15	0:00	0	S
 # There are too many San Joses elsewhere, so we'll use `Costa Rica'.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Costa_Rica	-5:36:20 -	LMT	1890		# San Jose
-			-5:36	-	SJMT	1921 Jan 15 # San Jose Mean Time
+			-5:36:20 -	SJMT	1921 Jan 15 # San Jose Mean Time
 			-6:00	CR	C%sT
 # Coco
 # no information; probably like America/Costa_Rica
 
 # Cuba
 
-# From Bob Devine (1988-01-28):
-# . . .DST is from 2nd Sunday in May to 2nd Sunday in October since 1981.
-# Change at midnight.  In 1979 & 1980, started at 3rd Sunday in March
-# (I think).
-
-# From U. S. Naval Observatory (1989-01-19):
-# CUBA                5 H  BEHIND UTC
-# CUBA                4 H  BEHIND UTC    MAR 20 - OCT 8
+# From Arthur David Olson (1999-03-29):
+# The 1999-03-28 exhibition baseball game held in Havana, Cuba, between
+# the Cuban National Team and the Baltimore Orioles was carried live on
+# the Orioles Radio Network, including affiliate WTOP in Washington, DC.
+# During the game, play-by-play announcer Jim Hunter noted that
+# "We'll be losing two hours of sleep...Cuba switched to Daylight Saving
+# Time today."  (The "two hour" remark referred to losing one hour of
+# sleep on 1999-03-28--when the announcers were in Cuba as it switched
+# to DST--and one more hour on 1999-04-04--when the announcers will have
+# returned to Baltimore, which switches on that date.)
 
-# From Shanks (1991):
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Cuba	1928	only	-	Jun	10	0:00	1:00	D
 Rule	Cuba	1928	only	-	Oct	10	0:00	0	S
@@ -1142,18 +1544,21 @@ Rule	Cuba	1969	1971	-	Oct	lastSun	0:00	0	S
 Rule	Cuba	1972	1974	-	Oct	8	0:00	0	S
 Rule	Cuba	1975	1977	-	Oct	lastSun	0:00	0	S
 Rule	Cuba	1978	only	-	May	7	0:00	1:00	D
-Rule	Cuba	1978	1980	-	Oct	Sun>=8	0:00	0	S
+Rule	Cuba	1978	1990	-	Oct	Sun>=8	0:00	0	S
 Rule	Cuba	1979	1980	-	Mar	Sun>=15	0:00	1:00	D
 Rule	Cuba	1981	1985	-	May	Sun>=5	0:00	1:00	D
-Rule	Cuba	1981	1990	-	Oct	Sun>=8	0:00	0	S
 Rule	Cuba	1986	1989	-	Mar	Sun>=14	0:00	1:00	D
-Rule	Cuba	1990	max	-	Apr	Sun>=1	0:00	1:00	D
+Rule	Cuba	1990	1997	-	Apr	Sun>=1	0:00	1:00	D
 Rule	Cuba	1991	1995	-	Oct	Sun>=8	0:00s	0	S
-Rule	Cuba	1996	max	-	Oct	Sun>=1	0:00s	0	S
+Rule	Cuba	1996	only	-	Oct	 6	0:00s	0	S
+Rule	Cuba	1997	only	-	Oct	12	0:00s	0	S
+Rule	Cuba	1998	1999	-	Mar	lastSun	0:00s	1:00	D
+Rule	Cuba	1998	max	-	Oct	lastSun	0:00s	0	S
+Rule	Cuba	2000	max	-	Apr	Sun>=1	0:00s	1:00	D
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Havana	-5:29:28 -	LMT	1890
-			-5:30	-	HMT	1925 Jul 19 12:00 # Havana MT
+			-5:29:36 -	HMT	1925 Jul 19 12:00 # Havana MT
 			-5:00	Cuba	C%sT
 
 # Dominica
@@ -1162,6 +1567,25 @@ Zone America/Dominica	-4:05:36 -	LMT	1911 Jul 1 0:01		# Roseau
 			-4:00	-	AST
 
 # Dominican Republic
+
+# From Steffen Thorsen (2000-10-30):
+# Enrique Morales reported to me that the Dominican Republic has changed the
+# time zone to Eastern Standard Time as of Sunday 29 at 2 am....
+# http://www.listin.com.do/antes/261000/republica/princi.html
+
+# From Paul Eggert (2000-12-04):
+# That URL (2000-10-26, in Spanish) says they planned to use US-style DST.
+
+# From Rives McDow (2000-12-01):
+# Dominican Republic changed its mind and presidential decree on Tuesday,
+# November 28, 2000, with a new decree.  On Sunday, December 3 at 1:00 AM the
+# Dominican Republic will be reverting to 8 hours from the International Date
+# Line, and will not be using DST in the foreseeable future.  The reason they
+# decided to use DST was to be in synch with Puerto Rico, who was also going
+# to implement DST.  When Puerto Rico didn't implement DST, the president
+# decided to revert.
+
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	DR	1966	only	-	Oct	30	0:00	1:00	D
 Rule	DR	1967	only	-	Feb	28	0:00	0	S
@@ -1173,6 +1597,8 @@ Rule	DR	1972	1974	-	Jan	21	0:00	0	S
 Zone America/Santo_Domingo -4:39:36 -	LMT	1890
 			-4:40	-	SDMT	1933 Apr  1 12:00 # S. Dom. MT
 			-5:00	DR	E%sT	1974 Oct 27
+			-4:00	-	AST	2000 Oct 29 02:00
+			-5:00	US	E%sT	2000 Dec  3 01:00
 			-4:00	-	AST
 
 # El Salvador
@@ -1211,9 +1637,9 @@ Zone America/Guatemala	-6:02:04 -	LMT	1918 Oct 5
 Rule	Haiti	1983	only	-	May	8	0:00	1:00	D
 Rule	Haiti	1984	1987	-	Apr	lastSun	0:00	1:00	D
 Rule	Haiti	1983	1987	-	Oct	lastSun	0:00	0	S
-# Shanks says AT is 2:00, but IATA SSIM (1991/1996) says 1:00s.  Go with IATA.
-Rule	Haiti	1988	max	-	Apr	Sun>=1	1:00s	1:00	D
-Rule	Haiti	1988	max	-	Oct	lastSun	1:00s	0	S
+# Shanks says AT is 2:00, but IATA SSIM (1991/1997) says 1:00s.  Go with IATA.
+Rule	Haiti	1988	1997	-	Apr	Sun>=1	1:00s	1:00	D
+Rule	Haiti	1988	1997	-	Oct	lastSun	1:00s	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Port-au-Prince -4:49:20 -	LMT	1890
 			-4:49	-	PPMT	1917 Jan 24 12:00 # P-a-P MT
@@ -1224,6 +1650,8 @@ Zone America/Port-au-Prince -4:49:20 -	LMT	1890
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Tegucigalpa -5:48:52 -	LMT	1921 Apr
 			-6:00	Salv	C%sT
+#
+# Great Swan I ceded by US to Honduras in 1972
 
 # Jamaica
 
@@ -1233,11 +1661,11 @@ Zone America/Tegucigalpa -5:48:52 -	LMT	1921 Apr
 # From U. S. Naval Observatory (1989-01-19):
 # JAMAICA             5 H  BEHIND UTC
 
-# From Shanks (1991):
+# From Shanks:
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Jamaica	-5:07:12 -	LMT	1890		# Kingston
-			-5:07	-	KMT	1912 Feb    # Kingston Mean Time
-			-5:00	-	EST	1974 Jan 6 2:00
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
+			-5:00	-	EST	1974 Apr 28 2:00
 			-5:00	US	E%sT	1984
 			-5:00	-	EST
 
@@ -1250,11 +1678,19 @@ Zone America/Martinique	-4:04:20 -      LMT	1890		# Fort-de-France
 			-4:00	-	AST
 
 # Montserrat
+# From Paul Eggert (1997-08-31):
+# Recent volcanic eruptions have forced evacuation of Plymouth, the capital.
+# Luckily, Olveston, the current de facto capital, has the same longitude.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
-Zone America/Montserrat	-4:08:52 -	LMT	1911 Jul 1 0:01   # Plymouth
+Zone America/Montserrat	-4:08:52 -	LMT	1911 Jul 1 0:01   # Olveston
 			-4:00	-	AST
 
 # Nicaragua
+#
+# From Steffen Thorsen (1998-12-29):
+# Nicaragua seems to be back at -6:00 but I have not been able to find when
+# they changed from -5:00.
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Nic	1979	1980	-	Mar	Sun>=16	0:00	1:00	D
 Rule	Nic	1979	1980	-	Jun	Mon>=23	0:00	0	S
@@ -1266,7 +1702,8 @@ Zone	America/Managua	-5:45:08 -	LMT	1890
 			-6:00	-	CST	1973 May
 			-5:00	-	EST	1975 Feb 16
 			-6:00	Nic	C%sT	1993 Jan 1 4:00
-			-5:00	-	EST
+			-5:00	-	EST	1998 Dec
+			-6:00	-	CST
 
 # Panama
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1303,12 +1740,12 @@ Zone America/Miquelon	-3:44:40 -	LMT	1911 May 15	# St Pierre
 # St Vincent and the Grenadines
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/St_Vincent	-4:04:56 -	LMT	1890		# Kingstown
-			-4:05	-	KMT	1912	   # Kingstown Mean Time
+			-4:04:56 -	KMT	1912	   # Kingstown Mean Time
 			-4:00	-	AST
 
 # Turks and Caicos
-# From Paul Eggert (1996-11-22):
-# Shanks says they use US DST rules, but IATA SSIM (1991/1996)
+# From Paul Eggert (1998-08-06):
+# Shanks says they use US DST rules, but IATA SSIM (1991/1998)
 # says they switch at midnight.  Go with IATA SSIM.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	TC	1979	1986	-	Apr	lastSun	0:00	1:00	D
@@ -1316,7 +1753,7 @@ Rule	TC	1979	max	-	Oct	lastSun	0:00	0	S
 Rule	TC	1987	max	-	Apr	Sun>=1	0:00	1:00	D
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Grand_Turk	-4:44:32 -	LMT	1890
-			-5:07	-	KMT	1912 Feb    # Kingston Mean Time
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
 			-5:00	TC	E%sT
 
 # British Virgin Is
diff --git a/zic.tproj/datfiles/southamerica b/zic.tproj/datfiles/southamerica
index 2e27ed0..96e371d 100644
--- a/zic.tproj/datfiles/southamerica
+++ b/zic.tproj/datfiles/southamerica
@@ -1,16 +1,17 @@
-#	$OpenBSD: southamerica,v 1.4 1997/01/14 04:36:57 millert Exp $
-# @(#)southamerica	7.16
+# @(#)southamerica	7.40
+
+# $FreeBSD: src/share/zoneinfo/southamerica,v 1.16 2001/04/06 16:46:52 wollman Exp $
 
 # This data is by no means authoritative; if you think you know better,
 # go ahead and edit the file (and please send any changes to
 # tz@elsie.nci.nih.gov for general use in the future).
 
-# From Paul Eggert <eggert@twinsun.com> (1996-11-22):
+# From Paul Eggert <eggert@twinsun.com> (1999-07-07):
 # A good source for time zone historical data outside the U.S. is
-# Thomas G. Shanks, The International Atlas (3rd edition),
-# San Diego: ACS Publications, Inc. (1991).
+# Thomas G. Shanks, The International Atlas (5th edition),
+# San Diego: ACS Publications, Inc. (1999).
 #
-# Gwillim Law <LAW@encmail.encompass.com> writes that a good source
+# Gwillim Law <Gwil_Law@bridge-point.com> writes that a good source
 # for recent time zone data is the International Air Transport
 # Association's Standard Schedules Information Manual (IATA SSIM),
 # published semiannually.  Law sent in several helpful summaries
@@ -19,17 +20,6 @@
 # Except where otherwise noted, Shanks is the source for entries through 1990,
 # and IATA SSIM is the source for entries after 1990.
 #
-# The following abbreviations are used in this file.
-# Corrections are welcome!
-#		std	dst
-#		LMT		Local Mean Time
-#	-2:00	FST	FDT	Fernando de Noronha
-#	-3:00	EST	EDT	Eastern Brazil
-#	-4:00	WST	WDT	Western Brazil
-#	-4:00	AST	ADT	Atlantic
-#	-5:00	AST	ADT	Acre
-#
-# See the `africa' file for time zone naming and abbreviation conventions.
 # Earlier editions of these tables used the North American style (e.g. ARST and
 # ARDT for Argentine Standard and Daylight Time), but the following quote
 # suggests that it's better to use European style (e.g. ART and ARST).
@@ -38,15 +28,24 @@
 #	in Europe and South America.
 #	-- E O Cutler, _New York Times_ (1937-02-14), quoted in
 #	H L Mencken, _The American Language: Supplement I_ (1960), p 466
-
-
-# From Guy Harris:
-# From Official Airline Guide - Worldwide Edition (1987).  Countries not
-# listed here do not observe DST, according to the OAG.  Time zone names
-# are pure inventions, and none are supplied for countries not observing
-# DST; updates from natives would be appreciated.  The times that DST
-# starts and ends are based on the assumption that they switch a 2AM just
-# as everybody else does.
+#
+# Earlier editions of these tables also used the North American style
+# for time zones in Brazil, but this was incorrect, as Brazilians say
+# "summer time".  Reinaldo Goulart, a Sao Paulo businessman active in
+# the railroad sector, writes (1999-07-06):
+#	The subject of time zones is currently a matter of discussion/debate in
+#	Brazil.  Let's say that "the Brasilia time" is considered the
+#	"official time" because Brasilia is the capital city.
+#	The other three time zones are called "Brasilia time "minus one" or
+#	"plus one" or "plus two".  As far as I know there is no such
+#	name/designation as "Eastern Time" or "Central Time".
+# So I invented the following (English-language) abbreviations for now.
+# Corrections are welcome!
+#		std	dst
+#	-2:00	FNT	FNST	Fernando de Noronha
+#	-3:00	BRT	BRST	Brasilia
+#	-4:00	AMT	AMST	Amazon
+#	-5:00	ACT	ACST	Acre
 
 ###############################################################################
 
@@ -83,12 +82,12 @@ Rule	Arg	1963	only	-	Dec	15	0:00	1:00	S
 Rule	Arg	1964	1966	-	Mar	 1	0:00	0	-
 Rule	Arg	1964	1966	-	Oct	15	0:00	1:00	S
 Rule	Arg	1967	only	-	Apr	 1	0:00	0	-
-Rule	Arg	1967	1968	-	Oct	Sun<=7	0:00	1:00	S
-Rule	Arg	1968	1969	-	Apr	Sun<=7	0:00	0	-
+Rule	Arg	1967	1968	-	Oct	Sun>=1	0:00	1:00	S
+Rule	Arg	1968	1969	-	Apr	Sun>=1	0:00	0	-
 Rule	Arg	1974	only	-	Jan	23	0:00	1:00	S
 Rule	Arg	1974	only	-	May	 1	0:00	0	-
-Rule	Arg	1974	1976	-	Oct	Sun<=7	0:00	1:00	S
-Rule	Arg	1975	1977	-	Apr	Sun<=7	0:00	0	-
+Rule	Arg	1974	1976	-	Oct	Sun>=1	0:00	1:00	S
+Rule	Arg	1975	1977	-	Apr	Sun>=1	0:00	0	-
 Rule	Arg	1985	only	-	Nov	 2	0:00	1:00	S
 Rule	Arg	1986	only	-	Mar	14	0:00	0	-
 Rule	Arg	1986	1987	-	Oct	25	0:00	1:00	S
@@ -102,7 +101,7 @@ Rule	Arg	1988	only	-	Dec	 1	0:00	1:00	S
 # Talleres de Hidrografia Naval Argentina
 # (Argentine Naval Hydrography Institute)
 #
-# Shanks gives 1989 Mar 16 and stops after 1990 Mar 4; go with Otero.
+# Shanks stops after 1992-03-01; go with Otero.
 Rule	Arg	1989	1993	-	Mar	Sun>=1	0:00	0	-
 Rule	Arg	1989	1992	-	Oct	Sun>=15	0:00	1:00	S
 #
@@ -111,23 +110,44 @@ Rule	Arg	1989	1992	-	Oct	Sun>=15	0:00	1:00	S
 # time corrections was derogated and no more modifications
 # to the time zones (for daylight saving) are now made.
 #
+# From Rives McDow (2000-01-10):
+# On October 3, 1999, 0:00 local, Argentina implemented daylight savings time,
+# which did not result in the switch of a time zone, as they stayed 9 hours
+# from the International Date Line.
+Rule	Arg	1999	only	-	Oct	Sun>=1	0:00	1:00	S
+Rule	Arg	2000	only	-	Mar	Sun>=1	0:00	0	-
+#
+# From Peter Gradelski via Steffen Thorsen (2000-03-01):
+# We just checked with our Sao Paulo office and they say the government of
+# Argentina decided not to become one of the countries that go on or off DST.
+# So Buenos Aires should be -3 hours from GMT at all times.
+#
+# From Fabian L. Arce Jofre <farcejofre@bigfoot.com> (2000-04-04):
+# The law that claimed DST for Argentina was derogated by President Fernando
+# de la Rua on March 2, 2000, because it would make people spend more energy
+# in the winter time, rather than less.  The change took effect on March 3.
+#
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
-# Buenos Aires (BA), Distrito Federal (DF), Santa Cruz (SC),
-# Tierra del Fuego (TF) & Antartida e Islas
+# Buenos Aires (BA), Capital Federal (CF), Santa Cruz (SC),
+# Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF)
 Zone America/Buenos_Aires -3:53:48 -	LMT	1894 Nov
 			-4:16:44 -	CMT	1920 May    # Cordoba Mean Time
 			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct 5
-			-3:00	Arg	AR%sT
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1999 Oct  3 0:00
+			-4:00	Arg	AR%sT	2000 Mar  3 0:00
+			-3:00	-	ART
 #
 # Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN), Chaco (CC),
 # Formosa (FM), La Pampa (LP), Chubut (CH)
 Zone America/Rosario	-4:02:40 -	LMT	1894 Nov
 			-4:16:44 -	CMT	1920 May
 			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct 5
+			-4:00	Arg	AR%sT	1969 Oct  5
 			-3:00	Arg	AR%sT	1991 Jul
+			-3:00	-	ART	1999 Oct  3 0:00
+			-4:00	Arg	AR%sT	2000 Mar  3 0:00
 			-3:00	-	ART
 #
 # Cordoba (CB), Santiago del Estero (SE), Salta (SA), Tucuman (TM), La Rioja (LR), San Juan (SJ), San Luis (SL),
@@ -135,8 +155,10 @@ Zone America/Rosario	-4:02:40 -	LMT	1894 Nov
 Zone America/Cordoba	-4:16:44 -	LMT	1894 Nov
 			-4:16:44 -	CMT	1920 May
 			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct 5
+			-4:00	Arg	AR%sT	1969 Oct  5
 			-3:00	Arg	AR%sT	1990 Jul
+			-3:00	-	ART	1999 Oct  3 0:00
+			-4:00	Arg	AR%sT	2000 Mar  3 0:00
 			-3:00	-	ART
 #
 # Jujuy (JY)
@@ -148,16 +170,20 @@ Zone America/Jujuy	-4:21:12 -	LMT	1894 Nov
 			-4:00	-	WART	1991 Oct  6
 			-4:00	1:00	WARST	1992 Mar 15
 			-4:00	-	WART	1992 Oct 18
+			-3:00	-	ART	1999 Oct  3 0:00
+			-4:00	Arg	AR%sT	2000 Mar  3 0:00
 			-3:00	-	ART
 #
 # Catamarca (CT)
 Zone America/Catamarca	-4:23:08 -	LMT	1894 Nov
 			-4:16:44 -	CMT	1920 May
 			-4:00	-	ART	1930 Dec
-			-4:00	Arg	AR%sT	1969 Oct 5
+			-4:00	Arg	AR%sT	1969 Oct  5
 			-3:00	Arg	AR%sT	1990 Jul
 			-3:00	-	ART	1991 Jul
 			-3:00	Arg	AR%sT	1992 Jul
+			-3:00	-	ART	1999 Oct  3 0:00
+			-4:00	Arg	AR%sT	2000 Mar  3 0:00
 			-3:00	-	ART
 #
 # Mendoza (MZ)
@@ -169,6 +195,8 @@ Zone America/Mendoza	-4:35:16 -	LMT	1894 Nov
 			-4:00	-	WART	1991 Oct 15
 			-4:00	1:00	WARST	1992 Mar  1
 			-4:00	-	WART	1992 Oct 18
+			-3:00	-	ART	1999 Oct  3 0:00
+			-4:00	Arg	AR%sT	2000 Mar  3 0:00
 			-3:00	-	ART
 
 # Aruba
@@ -186,14 +214,6 @@ Zone	America/La_Paz	-4:32:36 -	LMT	1890
 
 # Brazil
 
-# From Guy Harris:
-# The OAG lists 1987-10-25 and 1988-02-12 as the starting and
-# ending dates, giving them as "estimated date(s) based on previous year".  We
-# infer a rule here from one example, always a dangerous practice....  Yes,
-# they really do switch on Saturday, according to the OAG.
-# "[America/Porto_Acre]" is for the Territory of Acre;
-# "[America/Noronha]" is for Fernando De Noronha.
-
 # From Paul Eggert <eggert@twinsun.com> (1993-11-18):
 # The mayor of Rio recently attempted to change the time zone rules
 # just in his city, in order to leave more summer time for the tourist trade.
@@ -227,98 +247,238 @@ Zone	America/La_Paz	-4:32:36 -	LMT	1890
 # Maranhao (MA), Paraiba (PR), Pernambuco (PE), Piaui (PI), and Rio Grande do
 # Norte (RN), and the eastern part of Para (PA) are all in BR1 without DST.
 
-# From Paul Eggert (1996-11-22):
-# Let's make the following assumptions:
+# From Marcos Tadeu (1998-09-27):
+# <a href="http://pcdsh01.on.br/verao1.html">
+# Brazilian official page
+# </a>
+
+# From Jesper Norgaard (2000-11-03):
+# [For an official list of which regions in Brazil use which time zones, see:]
+# http://pcdsh01.on.br/Fusbr.htm
+# http://pcdsh01.on.br/Fusbrhv.htm
+
+# From Paul Eggert (2000-10-02):
+# The official decrees referenced below are taken from
+# <a href="http://pcdsh01.on.br/DecHV.html">
+# Decretos sobre o Horario de Verao no Brasil
+# </a> (1999-10-04, in Portuguese).
+# The official site for all decrees, including those not related to time, is
+# <a href="http://www.presidencia.gov.br/CCIVIL/decreto/principal_ano.htm">
+# Presidencia da Republica, Subchefia para Assuntos Juridicos, Decretos
+# </a> (in Portuguese).
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Decree <a href="http://pcdsh01.on.br/HV20466.htm">20,466</a> (1931-10-01)
+# Decree <a href="http://pcdsh01.on.br/HV21896.htm">21,896</a> (1932-01-10)
+Rule	Brazil	1931	only	-	Oct	 3	11:00	1:00	S
+Rule	Brazil	1932	1933	-	Apr	 1	 0:00	0	-
+Rule	Brazil	1932	only	-	Oct	 3	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV23195.htm">23,195</a> (1933-10-10)
+# revoked DST.
+# Decree <a href="http://pcdsh01.on.br/HV27496.htm">27,496</a> (1949-11-24)
+# Decree <a href="http://pcdsh01.on.br/HV27998.htm">27,998</a> (1950-04-13)
+Rule	Brazil	1949	1952	-	Dec	 1	 0:00	1:00	S
+Rule	Brazil	1950	only	-	Apr	16	 1:00	0	-
+Rule	Brazil	1951	1952	-	Apr	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV32308.htm">32,308</a> (1953-02-24)
+Rule	Brazil	1953	only	-	Mar	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV34724.htm">34,724</a> (1953-11-30)
+# revoked DST.
+# Decree <a href="http://pcdsh01.on.br/HV52700.htm">52,700</a> (1963-10-18)
+# established DST from 1963-10-23 00:00 to 1964-02-29 00:00
+# in SP, RJ, GB, MG, ES, due to the prolongation of the drought.
+# Decree <a href="http://pcdsh01.on.br/HV53071.htm">53,071</a> (1963-12-03)
+# extended the above decree to all of the national territory on 12-09.
+Rule	Brazil	1963	only	-	Dec	 9	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV53604.htm">53,604</a> (1964-02-25)
+# extended summer time by one day to 1964-03-01 00:00 (start of school).
+Rule	Brazil	1964	only	-	Mar	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV55639.htm">55,639</a> (1965-01-27)
+Rule	Brazil	1965	only	-	Jan	31	 0:00	1:00	S
+Rule	Brazil	1965	only	-	Mar	31	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV57303.htm">57,303</a> (1965-11-22)
+Rule	Brazil	1965	only	-	Dec	 1	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV57843.htm">57,843</a> (1966-02-18)
+Rule	Brazil	1966	1968	-	Mar	 1	 0:00	0	-
+Rule	Brazil	1966	1967	-	Nov	 1	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV63429.htm">63,429</a> (1968-10-15)
+# revoked DST.
+# Decree <a href="http://pcdsh01.on.br/HV91698.htm">91,698</a> (1985-09-27)
+Rule	Brazil	1985	only	-	Nov	 2	 0:00	1:00	S
+# Decree 92,310 (1986-01-21)
+# Decree 92,463 (1986-03-13)
+Rule	Brazil	1986	only	-	Mar	15	 0:00	0	-
+# Decree 93,316 (1986-10-01)
+Rule	Brazil	1986	only	-	Oct	25	 0:00	1:00	S
+Rule	Brazil	1987	only	-	Feb	14	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV94922.htm">94,922</a> (1987-09-22)
+Rule	Brazil	1987	only	-	Oct	25	 0:00	1:00	S
+Rule	Brazil	1988	only	-	Feb	 7	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV96676.htm">96,676</a> (1988-09-12)
+# except for the states of AC, AM, PA, RR, RO, and AP (then a territory)
+Rule	Brazil	1988	only	-	Oct	16	 0:00	1:00	S
+Rule	Brazil	1989	only	-	Jan	29	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV98077.htm">98,077</a> (1989-08-21)
+# with the same exceptions
+Rule	Brazil	1989	only	-	Oct	15	 0:00	1:00	S
+Rule	Brazil	1990	only	-	Feb	11	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV99530.htm">99,530</a> (1990-09-17)
+# adopted by RS, SC, PR, SP, RJ, ES, MG, GO, MS, DF.
+# Decree 99,629 (1990-10-19) adds BA, MT.
+Rule	Brazil	1990	only	-	Oct	21	 0:00	1:00	S
+Rule	Brazil	1991	only	-	Feb	17	 0:00	0	-
+# <a href="http://pcdsh01.on.br/HV1991.htm">Unnumbered decree</a> (1991-09-25)
+# adopted by RS, SC, PR, SP, RJ, ES, MG, BA, GO, MT, MS, DF.
+Rule	Brazil	1991	only	-	Oct	20	 0:00	1:00	S
+Rule	Brazil	1992	only	-	Feb	 9	 0:00	0	-
+# <a href="http://pcdsh01.on.br/HV1992.htm">Unnumbered decree</a> (1992-10-16)
+# adopted by same states.
+Rule	Brazil	1992	only	-	Oct	25	 0:00	1:00	S
+Rule	Brazil	1993	only	-	Jan	31	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV942.htm">942</a> (1993-09-28)
+# adopted by same states, plus AM.
+# Decree <a href="http://pcdsh01.on.br/HV1252.htm">1,252</a> (1994-09-22)
+# adopted by same states, minus AM.
+# Decree <a href="http://pcdsh01.on.br/HV1636.htm">1,636</a> (1995-09-14)
+# adopted by same states, plus TO.
+# Decree <a href="http://pcdsh01.on.br/HV1674.htm">1,674</a> (1995-10-13)
+# adds AL, SE.
+Rule	Brazil	1993	1995	-	Oct	Sun>=11	 0:00	1:00	S
+Rule	Brazil	1994	1995	-	Feb	Sun>=15	 0:00	0	-
+Rule	Brazil	1996	only	-	Feb	11	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV2000.htm">2,000</a> (1996-09-04)
+# adopted by same states, minus AL, SE.
+Rule	Brazil	1996	only	-	Oct	 6	 0:00	1:00	S
+Rule	Brazil	1997	only	-	Feb	16	 0:00	0	-
+# From Daniel C. Sobral <dcs@gns.com.br> (1998-02-12):
+# In 1997, the DS began on October 6. The stated reason was that
+# because international television networks ignored Brazil's policy on DS,
+# they bought the wrong times on satellite for coverage of Pope's visit.
+# This year, the ending date of DS was postponed to March 1
+# to help dealing with the shortages of electric power.
 #
-# * All data in Shanks are correct through 1990.  In particular,
-#   Shanks was right when he said Acre stopped observing DST in mid-1988.
-# * Areas where Shanks reports DST up to 1990, but the IATA reports no DST
-#   in 1995, stopped observing DST in mid-1990.
+# From Paul Eggert (1998-02-25):
+# <a href="http://churchnet.ucsm.ac.uk/news/files2/news165.htm">
+# Brazil Prepares for Papal Visit
+# </a>,
+# Church Net UK (1997-10-02).
 #
-# Under these assumptions Brazil needs 7 entries to cover all the distinct
-# time zone histories since 1970:
+# Decree 2,317 (1997-09-04), adopted by same states.
+Rule	Brazil	1997	only	-	Oct	 6	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/figuras/HV2495.JPG">2,495</a>
+# (1998-02-10)
+Rule	Brazil	1998	only	-	Mar	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/figuras/Hv98.jpg">2,780</a> (1998-09-11)
+# adopted by the same states as before.
+Rule	Brazil	1998	only	-	Oct	11	 0:00	1:00	S
+Rule	Brazil	1999	only	-	Feb	21	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/figuras/HV3150.gif">3,150</a>
+# (1999-08-23) adopted by same states.
+# Decree <a href="http://pcdsh01.on.br/DecHV99.gif">3,188</a> (1999-09-30)
+# adds SE, AL, PB, PE, RN, CE, PI, MA and RR.
+Rule	Brazil	1999	only	-	Oct	 3	 0:00	1:00	S
+Rule	Brazil	2000	only	-	Feb	27	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/DEC3592.htm">3,592</a> (2000-09-06)
+# adopted by the same states as before.
+# Decree <a href="http://pcdsh01.on.br/Dec3630.jpg">3,630</a> (2000-10-13)
+# repeals DST in PE and RR, effective 2000-10-15 00:00.
+# Decree <a href="http://pcdsh01.on.br/Dec3632.jpg">3,632</a> (2000-10-17)
+# repeals DST in SE, AL, PB, RN, CE, PI and MA, effective 2000-10-22 00:00.
 #
-# Noronha (UTC-2), Fortaleza (UTC-3), and Manaus (UTC-4) stopped observing DST
-#	in mid-1990.
-# Maceio (UTC-3) stopped observing DST in mid-1990, but started again mid-1995.
-# Sao Paulo (UTC-3) and Cuiaba (UTC-4) always observed DST.
-# Porto Acre (UTC-5) stopped observing DST in mid-1988.
+# These give only one year's rules.  After that, the rules are guesses
+# and are quite possibly wrong, but are more likely than no DST at all.
+Rule	Brazil	2000	max	-	Oct	Sun>=8	 0:00	1:00	S
+Rule	Brazil	2001	max	-	Feb	Sun>=15	 0:00	0	-
 
-# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Brazil	1931	only	-	Oct	 3	11:00	1:00	D
-Rule	Brazil	1932	1933	-	Apr	 1	 0:00	0	S
-Rule	Brazil	1932	only	-	Oct	 3	 0:00	1:00	D
-Rule	Brazil	1949	1952	-	Dec	 1	 0:00	1:00	D
-Rule	Brazil	1950	only	-	Apr	16	 0:00	0	S
-Rule	Brazil	1951	1953	-	Apr	 1	 0:00	0	S
-Rule	Brazil	1963	only	-	Dec	 9	 0:00	1:00	D
-Rule	Brazil	1964	only	-	Mar	 1	 0:00	0	S
-Rule	Brazil	1965	only	-	Jan	31	 0:00	1:00	D
-Rule	Brazil	1965	only	-	Apr	 1	 0:00	0	S
-Rule	Brazil	1965	only	-	Dec	 1	 0:00	1:00	D
-Rule	Brazil	1966	1968	-	Mar	 1	 0:00	0	S
-Rule	Brazil	1966	1967	-	Nov	 1	 0:00	1:00	D
-Rule	Brazil	1985	only	-	Nov	 2	 0:00	1:00	D
-Rule	Brazil	1986	only	-	Mar	15	 0:00	0	S
-Rule	Brazil	1986	1987	-	Oct	Sat<=28	 0:00	1:00	D
-Rule	Brazil	1987	only	-	Feb	14	 0:00	0	S
-Rule	Brazil	1988	only	-	Feb	 7	 0:00	0	S
-Rule	Brazil	1989	only	-	Jan	22	 0:00	0	S
-Rule	Brazil	1988	1989	-	Oct	Sun>=10	 0:00	1:00	D
-Rule	Brazil	1990	1991	-	Feb	Sun>=11	 0:00	0	S
-Rule	Brazil	1990	1992	-	Oct	Sun>=20	 0:00	1:00	D
-Rule	Brazil	1992	only	-	Feb	 9	 0:00	0	S
-Rule	Brazil	1993	max	-	Oct	Sun>=11	 0:00	1:00	D
-Rule	Brazil	1993	only	-	Jan	31	 0:00	0	S
-Rule	Brazil	1994	1995	-	Feb	Sun>=15	 0:00	0	S
-Rule	Brazil	1996	max	-	Feb	Sun>=11	 0:00	0	S
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
-# Fernando de Noronha
+# Atlantic islands: Fernando de Noronha, Trindade, Martin Vaz,
+# Atol das Rocas, and Penedos de Sao Pedro e Sao Paulo
 Zone America/Noronha	-2:09:40 -	LMT	1914
-			-2:00	-	FST	1963 Dec 9
-			-2:00	Brazil	F%sT	1990 Jul
-			-2:00	-	FST
+			-2:00	Brazil	FN%sT	1990 Sep 17
+			-2:00	-	FNT
 #
-# Amapa, east Para, Maranhao, Piaui, Ceara, Rio Grande do Norte, Paraiba,
-# Pernambuco (except Fernando de Noronha)
+# Amapa (AP), east Para (PA)
+# East Para includes Belem, Maraba, Serra Norte, and Sao Felix do Xingu.
+Zone America/Belem	-3:13:56 -	LMT	1914
+			-3:00	Brazil	BR%sT	1988 Sep 12
+			-3:00	-	BRT
+#
+# Maranhao (MA), Piaui (PI), Ceara (CE), Rio Grande do Norte (RN),
+# Paraiba (PB)
 Zone America/Fortaleza	-2:34:00 -	LMT	1914
-			-3:00	-	EST	1963 Dec 9
-			-3:00	Brazil	E%sT	1990 Jul
-			-3:00	-	EST
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1999 Sep 30
+			-3:00	Brazil	BR%sT	2000 Oct 22
+			-3:00	-	BRT
+#
+# Pernambuco (PE) (except Atlantic islands)
+Zone America/Recife	-2:19:36 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1999 Sep 30
+			-3:00	Brazil	BR%sT	2000 Oct 15
+			-3:00	-	BRT
 #
-# Alagoas, Sergipe, Tocantins
+# Tocantins (TO)
+Zone America/Araguaina	-3:12:48 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1995 Sep 14
+			-3:00	Brazil	BR%sT
+#
+# Alagoas (AL), Sergipe (SE)
 Zone America/Maceio	-2:22:52 -	LMT	1914
-			-3:00	-	EST	1963 Dec 9
-			-3:00	Brazil	E%sT	1990 Jul
-			-3:00	-	EST	1995 Jul
-			-3:00	Brazil	E%sT
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1995 Oct 13
+			-3:00	Brazil	BR%sT	1996 Sep  4
+			-3:00	-	BRT	1999 Sep 30
+			-3:00	Brazil	BR%sT	2000 Oct 22
+			-3:00	-	BRT
 #
-# Bahia, Goias, Distrito Federal, Minas Gerais, Espirito Santo, Rio de Janeiro,
-# Sao Paulo, Parana, Santa Catarina, Rio Grande do Sul
+# Bahia (BA), Goias (GO), Distrito Federal (DF), Minas Gerais (MG),
+# Espirito Santo (ES), Rio de Janeiro (RJ), Sao Paulo (SP), Parana (PR),
+# Santa Catarina (SC), Rio Grande do Sul (RS)
 Zone America/Sao_Paulo	-3:06:28 -	LMT	1914
-			-3:00	Brazil	E%sT
+			-3:00	Brazil	BR%sT	1963 Oct 23 00:00
+			-3:00	1:00	BRST	1964
+			-3:00	Brazil	BR%sT
 #
 # Mato Grosso, Mato Grosso do Sul
 Zone America/Cuiaba	-3:44:20 -	LMT	1914
-			-4:00	-	WST	1963 Dec 9
-			-4:00	Brazil	W%sT
+			-4:00	Brazil	AM%sT
+#
+# west Para (PA), Rondonia (RO)
+# West Para includes Altamira, Oribidos, Prainha, Oriximina, and Santarem.
+Zone America/Porto_Velho -4:15:36 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT
+#
+# Roraima (RR)
+Zone America/Boa_Vista	-4:02:40 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT	1999 Sep 30
+			-4:00	Brazil	AM%sT	2000 Oct 15
+			-4:00	-	AMT
 #
-# Roraima, west Para, Amazonas, Rondonia
+# east Amazonas (AM): Boca do Acre, Jutai, Manaus, Floriano Peixoto
 Zone America/Manaus	-4:00:04 -	LMT	1914
-			-4:00	-	WST	1963 Dec 9
-			-4:00	Brazil	W%sT	1990 Jul
-			-4:00	-	WST
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT	1993 Sep 28
+			-4:00	Brazil	AM%sT	1994 Sep 22
+			-4:00	-	AMT
 #
-# Acre
-# Rio_Branco is too ambiguous, since there's a Rio Branco in Uruguay too.
-Zone America/Porto_Acre	-4:31:12 -	LMT	1914
-			-5:00	-	AST	1963 Dec 9
-			-5:00	Brazil	A%sT	1988 Jul
-			-5:00	-	AST
+# west Amazonas (AM): Atalaia do Norte, Boca do Maoco, Benjamin Constant,
+#	Eirunepe, Envira, Ipixuna
+Zone America/Eirunepe	-4:39:28 -	LMT	1914
+			-5:00	Brazil	AC%sT	1988 Sep 12
+			-5:00	-	ACT	1993 Sep 28
+			-5:00	Brazil	AC%sT	1994 Sep 22
+			-5:00	-	ACT
 #
-# Martin Vaz and Trinidade are like America/Noronha.
+# Acre (AC)
+Zone America/Rio_Branco	-4:31:12 -	LMT	1914
+			-5:00	Brazil	AC%sT	1988 Sep 12
+			-5:00	-	ACT
 
 
 # Chile
@@ -326,16 +486,40 @@ Zone America/Porto_Acre	-4:31:12 -	LMT	1914
 # From Eduardo Krell (1995-10-19):
 # The law says to switch to DST at midnight [24:00] on the second SATURDAY
 # of October....  The law is the same for March and October.
+# (1998-09-29):
+# Because of the drought this year, the government decided to go into
+# DST earlier (saturday 9/26 at 24:00). This is a one-time change only ...
+# (unless there's another dry season next year, I guess).
+
+# From Julio I. Pacheco Troncoso (1999-03-18):
+# Because of the same drought, the government decided to end DST later,
+# on April 3, (one-time change).
+
+# From Gwillim Law (2001-02-20):
+# I came across a Chilean on-line newspaper, La Tercera.  Its
+# <a href="http://www.tercera.cl/diario/1998/03/13/extras.html">
+# 1998-03-13 issue
+# </a>, says (my translation):
+# "At 24:00 (midnight) tomorrow (Saturday) - 22:00 in the insular
+# territory [Easter Island, Juan Fernandez, etc.] - winter time will
+# begin in the entire country."
+
+# From Paul Eggert (2001-02-21):
+# Assume this rule has been used since DST was introduced in the islands.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Chile	1918	only	-	Sep	1	0:00	1:00	S
-Rule	Chile	1919	only	-	Jul	2	0:00	0	-
-Rule	Chile	1927	1931	-	Sep	1	0:00	1:00	S
-Rule	Chile	1928	1932	-	Apr	1	0:00	0	-
-Rule	Chile	1969	max	-	Oct	Sun>=9	0:00	1:00	S
-Rule	Chile	1970	max	-	Mar	Sun>=9	0:00	0	-
+Rule	Chile	1918	only	-	Sep	 1	0:00	1:00	S
+Rule	Chile	1919	only	-	Jul	 2	0:00	0	-
+Rule	Chile	1927	1931	-	Sep	 1	0:00	1:00	S
+Rule	Chile	1928	1932	-	Apr	 1	0:00	0	-
+Rule	Chile	1969	1997	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	1970	1998	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	1998	only	-	Sep	27	4:00u	1:00	S
+Rule	Chile	1999	only	-	Apr	 4	3:00u	0	-
+Rule	Chile	1999	max	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	2000	max	-	Mar	Sun>=9	3:00u	0	-
 # IATA SSIM anomalies: (1990-09) says 1990-09-16; (1992-02) says 1992-03-14;
-# (1996-09) says 1998-03-08.  Ignore these for now.
+# (1996-09) says 1998-03-08.  Ignore these.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Santiago	-4:42:40 -	LMT	1890
 			-4:42:40 -	SMT	1910	    # Santiago Mean Time
@@ -352,6 +536,8 @@ Zone Pacific/Easter	-7:17:28 -	LMT	1890	    # Mataveri
 
 
 # Colombia
+# Shanks specifies 24:00 for 1992 transition times; go with IATA,
+# as it seems implausible to change clocks at midnight New Year's Eve.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	CO	1992	only	-	May	 2	0:00	1:00	S
 Rule	CO	1992	only	-	Dec	31	0:00	0	-
@@ -363,6 +549,10 @@ Zone	America/Bogota	-4:56:20 -	LMT	1884 Mar 13
 # no information; probably like America/Bogota
 
 # Curacao
+# Shanks says that Bottom and Oranjestad have been at -4:00 since
+# standard time was introduced on 1912-03-02; and that Kralendijk and Rincon
+# used Kralendijk Mean Time (-4:33:08) from 1912-02-02 to 1965-01-01.
+# This all predates our 1970 cutoff, though.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Curacao	-4:35:44 -	LMT	1912 Feb 12	# Willemstad
 			-4:30	-	ANT	1965 # Netherlands Antilles Time
@@ -378,6 +568,56 @@ Zone Pacific/Galapagos	-5:58:24 -	LMT	1931 # Puerto Baquerizo Moreno
 			-6:00	-	GALT	     # Galapagos Time
 
 # Falklands
+
+# From Paul Eggert (2001-03-05):
+# Between 1990 and 2000 inclusive, Shanks and the IATA agree except
+# the IATA gives 1996-09-08.  Go with Shanks.
+
+# From Falkland Islands Government Office, London (2001-01-22)
+# via Jesper Norgaard:
+# ... the clocks revert back to Local Mean Time at 2 am on Sunday 15
+# April 2001 and advance one hour to summer time at 2 am on Sunday 2
+# September.  It is anticipated that the clocks will revert back at 2
+# am on Sunday 21 April 2002 and advance to summer time at 2 am on
+# Sunday 1 September.
+
+# From Rives McDow (2001-02-13):
+#
+# I have communicated several times with people there, and the last
+# time I had communications that was helpful was in 1998.  Here is
+# what was said then:
+#
+# "The general rule was that Stanley used daylight saving and the Camp
+# did not. However for various reasons many people in the Camp have
+# started to use daylight saving (known locally as 'Stanley Time')
+# There is no rule as to who uses daylight saving - it is a matter of
+# personal choice and so it is impossible to draw a map showing who
+# uses it and who does not. Any list would be out of date as soon as
+# it was produced. This year daylight saving ended on April 18/19th
+# and started again on September 12/13th.  I do not know what the rule
+# is, but can find out if you like.  We do not change at the same time
+# as UK or Chile."
+#
+# I did have in my notes that the rule was "Second Saturday in Sep at
+# 0:00 until third Saturday in Apr at 0:00".  I think that this does
+# not agree in some cases with Shanks; is this true?
+#
+# Also, there is no mention in the list that some areas in the
+# Falklands do not use DST.  I have found in my communications there
+# that these areas are on the western half of East Falkland and all of
+# West Falkland.  Stanley is the only place that consistently observes
+# DST.  Again, as in other places in the world, the farmers don't like
+# it.  West Falkland is almost entirely sheep farmers.
+#
+# I know one lady there that keeps a list of which farm keeps DST and
+# which doesn't each year.  She runs a shop in Stanley, and says that
+# the list changes each year.  She uses it to communicate to her
+# customers, catching them when they are home for lunch or dinner.
+
+# From Paul Eggert (2001-03-05):
+# For now, we'll just record the time in Stanley, since we have no
+# better info.
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Falk	1937	1938	-	Sep	lastSun	0:00	1:00	S
 Rule	Falk	1938	1942	-	Mar	Sun>=19	0:00	0	-
@@ -387,9 +627,10 @@ Rule	Falk	1943	only	-	Jan	1	0:00	0	-
 Rule	Falk	1983	only	-	Sep	lastSun	0:00	1:00	S
 Rule	Falk	1984	1985	-	Apr	lastSun	0:00	0	-
 Rule	Falk	1984	only	-	Sep	16	0:00	1:00	S
-Rule	Falk	1985	1995	-	Sep	Sun>=9	0:00	1:00	S
-Rule	Falk	1986	max	-	Apr	Sun>=16	0:00	0	-
-Rule	Falk	1996	max	-	Sep	Sun>=8	0:00	1:00	S
+Rule	Falk	1985	2000	-	Sep	Sun>=9	0:00	1:00	S
+Rule	Falk	1986	2000	-	Apr	Sun>=16	0:00	0	-
+Rule	Falk	2001	max	-	Apr	Sun>=15	2:00	0	-
+Rule	Falk	2001	max	-	Sep	Sun>=1	2:00	1:00	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Atlantic/Stanley	-3:51:24 -	LMT	1890
 			-3:51:24 -	SMT	1912 Mar 12  # Stanley Mean Time
@@ -413,31 +654,49 @@ Zone	America/Guyana	-3:52:40 -	LMT	1915 Mar	# Georgetown
 			-4:00	-	GYT
 
 # Paraguay
-
-# From Bob Devine (1988-01-28):
-# Paraguay: First day in October to last in March.  Midnight switch??
-# Since 1980.
-
-# From U. S. Naval Observatory (1989-01-19):
-# PARAGUAY            4 H  BEHIND UTC
-# PARAGUAY            3 H  BEHIND UTC    OCT 1, '88-MAR 31, '89
-
-# From Shanks (1991):
+# From Paul Eggert (1999-10-29):
+# Shanks (1999) says that spring transitions are from 01:00 -> 02:00,
+# and autumn transitions are from 00:00 -> 23:00.  Go with earlier
+# editions of Shanks, and with the IATA, who say transitions occur at 00:00.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	Para	1975	1978	-	Oct	 1	0:00	1:00	S
+Rule	Para	1975	1988	-	Oct	 1	0:00	1:00	S
 Rule	Para	1975	1978	-	Mar	 1	0:00	0	-
-# Shanks says 1979 was all DST.
-Rule	Para	1980	1991	-	Apr	 1	0:00	0	-
-Rule	Para	1980	1988	-	Oct	 1	0:00	1:00	S
+Rule	Para	1979	1991	-	Apr	 1	0:00	0	-
 Rule	Para	1989	only	-	Oct	22	0:00	1:00	S
 Rule	Para	1990	only	-	Oct	 1	0:00	1:00	S
 Rule	Para	1991	only	-	Oct	 6	0:00	1:00	S
 Rule	Para	1992	only	-	Mar	 1	0:00	0	-
 Rule	Para	1992	only	-	Oct	 5	0:00	1:00	S
 Rule	Para	1993	only	-	Mar	31	0:00	0	-
-Rule	Para	1993	max	-	Oct	 1	0:00	1:00	S
+Rule	Para	1993	1995	-	Oct	 1	0:00	1:00	S
 Rule	Para	1994	1995	-	Feb	lastSun	0:00	0	-
-Rule	Para	1996	max	-	Mar	 1	0:00	0	-
+Rule	Para	1996	only	-	Mar	 1	0:00	0	-
+# IATA SSIM (2000-02) says 1999-10-10; ignore this for now.
+# From Steffen Thorsen (2000-10-02):
+# I have three independent reports that Paraguay changed to DST this Sunday
+# (10-01).
+#
+# Translated by Gwillim Law (2001-02-27) from
+# <a href="http://www.diarionoticias.com.py/011000/nacional/naciona1.htm">
+# Noticias, a daily paper in Asuncion, Paraguay (2000-10-01)
+# </a>:
+# Starting at 0:00 today, the clock will be set forward 60 minutes, in
+# fulfillment of Decree No. 7,273 of the Executive Power....  The time change
+# system has been operating for several years.  Formerly there was a separate
+# decree each year; the new law has the same effect, but permanently.  Every
+# year, the time will change on the first Sunday of October; likewise, the
+# clock will be set back on the first Sunday of March.
+#
+# From Jesper Norgaard (2001-03-06) [an official URL saying similar things]:
+# http://gateway.abc.com.py:8000/pub/pag04.mbr/artic?FHA=2001-03-03-02.24.52.900592
+#
+Rule	Para	1996	max	-	Oct	Sun>=1	0:00	1:00	S
+# IATA SSIM (1997-09) says Mar 1; go with Shanks.
+Rule	Para	1997	only	-	Feb	lastSun	0:00	0	-
+# Shanks says 1999-02-28; IATA SSIM (1999-02) says 1999-02-27, but
+# (1999-09) reports no date; go with above sources and Gerd Knops (2001-02-27).
+Rule	Para	1998	max	-	Mar	Sun>=1	0:00	0	-
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Asuncion	-3:50:40 -	LMT	1890
 			-3:50:40 -	AMT	1931 Oct 10 # Asuncion Mean Time
@@ -455,8 +714,9 @@ Rule	Peru	1987	only	-	Jan	 1	0:00	1:00	S
 Rule	Peru	1987	only	-	Apr	 1	0:00	0	-
 Rule	Peru	1990	only	-	Jan	 1	0:00	1:00	S
 Rule	Peru	1990	only	-	Apr	 1	0:00	0	-
-Rule	Peru	1993	only	-	Jan	 1	0:00	1:00	S
-Rule	Peru	1993	only	-	Apr	 1	0:00	0	-
+# IATA is ambiguous for 1993/1995; go with Shanks.
+Rule	Peru	1994	only	-	Jan	 1	0:00	1:00	S
+Rule	Peru	1994	only	-	Apr	 1	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Lima	-5:08:12 -	LMT	1890
 			-5:09	-	LMT	1908 Jul 28 # Lima Mean Time
@@ -468,7 +728,7 @@ Zone Atlantic/South_Georgia -2:26:08 -	LMT	1890		# Grytviken
 			-2:00	-	GST	# South Georgia Time
 
 # South Sandwich Is
-# uninhabited
+# uninhabited; scientific personnel have wintered
 
 # Suriname
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -487,7 +747,7 @@ Zone America/Port_of_Spain -4:06:04 -	LMT	1912 Mar 2
 # Uruguay
 # From Paul Eggert <eggert@twinsun.com> (1993-11-18):
 # Uruguay wins the prize for the strangest peacetime manipulation of the rules.
-# From Shanks (1991):
+# From Shanks:
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 # Whitman gives 1923 Oct 1; go with Shanks.
 Rule	Uruguay	1923	only	-	Oct	 2	 0:00	0:30	HS
@@ -529,9 +789,11 @@ Rule	Uruguay	1988	only	-	Mar	14	 0:00	0	-
 Rule	Uruguay	1988	only	-	Dec	11	 0:00	1:00	S
 Rule	Uruguay	1989	only	-	Mar	12	 0:00	0	-
 Rule	Uruguay	1989	only	-	Oct	29	 0:00	1:00	S
+# Shanks says no DST was observed in 1990/1 and 1991/2,
+# and that 1992/3's DST was from 10-25 to 03-01.  Go with IATA.
 Rule	Uruguay	1990	1992	-	Mar	Sun>=1	 0:00	0	-
 Rule	Uruguay	1990	1991	-	Oct	Sun>=21	 0:00	1:00	S
-Rule	Uruguay	1992	1993	-	Oct	Sun>=15	 0:00	1:00	S
+Rule	Uruguay	1992	only	-	Oct	18	 0:00	1:00	S
 Rule	Uruguay	1993	only	-	Feb	28	 0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Montevideo	-3:44:44 -	LMT	1898 Jun 28
diff --git a/zic.tproj/datfiles/systemv b/zic.tproj/datfiles/systemv
index 05a939d..c6a6b64 100644
--- a/zic.tproj/datfiles/systemv
+++ b/zic.tproj/datfiles/systemv
@@ -1,36 +1,50 @@
-#	$OpenBSD: systemv,v 1.2 1997/01/14 04:36:58 millert Exp $
-# @(#)systemv	7.2
+# @(#)systemv	7.3
 
 # Old rules, should the need arise.
 # No attempt is made to handle Newfoundland, since it cannot be expressed
 # using the System V "TZ" scheme (half-hour offset), or anything outside
 # North America (no support for non-standard DST start/end dates), nor
-# the change in the DST rules in the US in 1987 (can't split between
-# Canada, with no changes, and the US)
+# the change in the DST rules in the US in 1987 (which occurred before
+# the old rules were written).
 #
-# Be sure to compile this *without* leap second correction for true conformance.
+# If you need the old rules, uncomment ## lines and comment-out Link lines.
+# Compile this *without* leap second correction for true conformance.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
-Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
-Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
-Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
-Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
-Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
-Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
-Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
+## Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
+## Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
+## Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
+## Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
+## Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
+## Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
+## Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
+## Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
 
 # Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
-Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
-Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
-Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
-Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
-Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
-Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
-Zone	SystemV/AST4	-4:00	-		AST
-Zone	SystemV/EST5	-5:00	-		EST
-Zone	SystemV/CST6	-6:00	-		CST
-Zone	SystemV/MST7	-7:00	-		MST
-Zone	SystemV/PST8	-8:00	-		PST
-Zone	SystemV/YST9	-9:00	-		YST
-Zone	SystemV/HST10	-10:00	-		HST
+## Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
+## Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
+## Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
+## Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
+## Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
+## Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
+## Zone	SystemV/AST4	-4:00	-		AST
+## Zone	SystemV/EST5	-5:00	-		EST
+## Zone	SystemV/CST6	-6:00	-		CST
+## Zone	SystemV/MST7	-7:00	-		MST
+## Zone	SystemV/PST8	-8:00	-		PST
+## Zone	SystemV/YST9	-9:00	-		YST
+## Zone	SystemV/HST10	-10:00	-		HST
+# For now...
+Link	America/Halifax		SystemV/AST4ADT
+Link	America/New_York	SystemV/EST5EDT
+Link	America/Chicago		SystemV/CST6CDT
+Link	America/Denver		SystemV/MST7MDT
+Link	America/Los_Angeles	SystemV/PST8PDT
+Link	America/Anchorage	SystemV/YST9YDT
+Link	America/Puerto_Rico	SystemV/AST4
+Link	America/Indianapolis	SystemV/EST5
+Link	America/Regina		SystemV/CST6
+Link	America/Phoenix		SystemV/MST7
+Link	Pacific/Pitcairn	SystemV/PST8
+Link	Pacific/Gambier		SystemV/YST9
+Link	Pacific/Honolulu	SystemV/HST10
-- 
2.45.2