about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog175
-rw-r--r--Makeconfig12
-rw-r--r--Makefile2
-rw-r--r--Makerules18
-rwxr-xr-xconfigure110
-rw-r--r--configure.in18
-rw-r--r--csu/initfini.c43
-rw-r--r--elf/dl-deps.c3
-rw-r--r--gnu-versions.h2
-rw-r--r--io/fstat.c41
-rw-r--r--io/lstat.c41
-rw-r--r--io/mknod.c42
-rw-r--r--io/stat.c41
-rw-r--r--libio/libio.h3
-rw-r--r--libio/strfile.h4
-rw-r--r--libio/strops.c119
-rw-r--r--login/Makefile13
-rw-r--r--login/getutent.c34
-rw-r--r--login/getutent_r.c211
-rw-r--r--login/getutid.c36
-rw-r--r--login/getutid_r.c118
-rw-r--r--login/getutline.c36
-rw-r--r--login/getutline_r.c91
-rw-r--r--login/login.c81
-rw-r--r--login/logout.c11
-rw-r--r--login/logwtmp.c28
-rw-r--r--login/utmp-private.h41
-rw-r--r--login/utmp.h43
-rw-r--r--login/utmp_db.c102
-rw-r--r--login/utmp_file.c385
-rw-r--r--nss/getXXbyYY_r.c4
-rw-r--r--nss/getXXent_r.c4
-rw-r--r--nss/nsswitch.c4
-rw-r--r--posix/Makefile2
-rw-r--r--posix/sys/types.h2
-rw-r--r--posix/wait.h1
-rwxr-xr-xrellns-sh16
-rw-r--r--shlib-versions38
-rw-r--r--stdio-common/Makefile8
-rw-r--r--stdlib/stdlib.h8
-rw-r--r--stdlib/strtod.c3
-rw-r--r--sysdeps/alpha/elf/Dist2
-rw-r--r--sysdeps/alpha/elf/crtbegin.S91
-rw-r--r--sysdeps/alpha/elf/crtend.S92
-rw-r--r--sysdeps/generic/paths.h1
-rw-r--r--sysdeps/generic/pty.c5
-rw-r--r--sysdeps/gnu/utmpbits.h34
-rw-r--r--sysdeps/mach/hurd/Dist2
-rw-r--r--sysdeps/mach/hurd/Makefile9
-rw-r--r--sysdeps/mach/hurd/libc_p-ldscript5
-rw-r--r--sysdeps/posix/getcwd.c5
-rw-r--r--sysdeps/stub/getlogin.c29
-rw-r--r--sysdeps/stub/getlogin_r.c28
-rw-r--r--sysdeps/unix/getlogin.c35
-rw-r--r--sysdeps/unix/getlogin_r.c37
-rw-r--r--sysdeps/unix/sysv/linux/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/Makefile3
-rw-r--r--sysdeps/unix/sysv/linux/paths.h1
-rw-r--r--sysdeps/unix/sysv/linux/sys/serial.h110
-rw-r--r--time/Makefile2
-rw-r--r--time/africa41
-rw-r--r--time/antarctica32
-rw-r--r--time/asia156
-rw-r--r--time/australasia61
-rw-r--r--time/etcetera20
-rw-r--r--time/europe225
-rw-r--r--time/northamerica82
-rw-r--r--time/southamerica217
-rw-r--r--time/zone.tab35
69 files changed, 2478 insertions, 877 deletions
diff --git a/ChangeLog b/ChangeLog
index 130d064408..d7fed11e61 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,178 @@
+Wed Nov 27 06:10:10 1996  Ulrich Drepper  <drepper@cygnus.com>
+
+	* Makefile: Fix typo.
+
+	* configure: Require autoconf-2.11.
+
+	* elf/dl-deps.c: Terminate duplicate list.
+
+	* libio/libio.h: Add prototypes for _IO_seekoff and _IO_seekpos.
+	* libio/strfile.h: Update from current libg++.
+	* libio/strops.c: Likewise.
+
+	* login/Makefile (routines): Update after correction of reentrant
+	interface.
+	* login/endutent.c: Removed.
+	* login/endutent_r.c: Likewise.
+	* login/pututline.c: Likewise.
+	* login/pututline_r.c: Likewise.
+	* login/setutent.c: Likewise.
+	* login/setutent_r.c: Likewise.
+	* login/getutent.c: Update for new interface.
+	* login/getutent_r.c: Likewise.
+	* login/getutid.c: Likewise.
+	* login/getutid_r.c: Likewise.
+	* login/getutline.c: Likewise.
+	* login/getutline_r.c: Likewise.
+	* login/login.c: Likewise.
+	* login/logout.c: Likewise.
+	* login/logwtmp.c: Likewise.
+	* login/utmp.h: Likewise.
+	* sysdeps/unix/getlogin.c: Likewise.
+	* sysdeps/unix/getlogin_r.c: Likewise.
+	* login/utmp-private.h: New private header.
+	* login/utmp_db.c: Stub DB backend for utmp handler.
+	* login/utmp_file.c: File backend for utmp handler.
+	* sysdeps/gnu/utmpbits.h (struct utmp): Add some more fields.
+	(enum utlogin): List of record types.
+	(struct exit_status): Record to align with other implementations.
+
+	* sysdeps/generic/paths.h: Add _PATH_UTMP_DB.
+	* sysdeps/unix/sysv/linux/paths.h: Likewise.
+
+	* sysdeps/generic/pty.c: Use getgrnam_r instead of getgrnam.
+
+	* sysdeps/stub/getlogin.c: Update copyright.
+	* sysdeps/stub/getlogin_r.c: Likewise.
+
+	* nss/getXXbyYY_r.c: Use -1l for error-pointer value instead of -1.
+	* nss/getXXent_r.c: Likewise.
+	* nss/nsswitch.c: Likewise.
+
+	* posix/Makefile (headers): Add wait.h.
+	* posix/wait.h: New file.
+
+	* posix/sys/types.h: Always define intN_t types.
+
+	* stdio-common/Makefile: Update copyright.
+	Use -Wno-format flag for scanf4.c and scanf7.c.
+
+	* stdlib/stdlib.h: Reformat.
+
+	* time/africa: Update from ADO tzdata1996m.
+	* time/antarctica: Likewise.
+	* time/asia: Likewise.
+	* time/australia: Likewise.
+	* time/etcetera: Likewise.
+	* time/europe: Likewise.
+	* time/northamerica: Likewise.
+	* time/southamerica: Likewise.
+	* time/zone.tab: Likewise.
+
+Fri Nov 22 19:34:12 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* sysdeps/posix/getcwd.c (__getcwd): After resizing the buffer
+	move the current contents to the end and relocate file name
+	pointer to upper half of the buffer.
+
+Sun Nov 24 04:56:19 1996  Ulrich Drepper  <drepper@cygnus.com>
+
+	* time/africa: Update from ADO tzdata1996m.
+	* time/antarctica: Likewise.
+	* time/asia: Likewise.
+	* time/australia: Likewise.
+	* time/etcetera: Likewise.
+	* time/europe: Likewise.
+	* time/nothamerica: Likewise.
+	* time/southameria: Likewise.
+	* time/zone.tab: Likewise.
+
+	* sysdeps/unix/sysv/linux/sys/serial.h: New file.
+	* sysdeps/unix/sysv/linux/Makefile [$(subdir)=misc] (sysdep_headers):
+	Add sys/serial.h.
+	* sysdeps/unix/sysv/linux/Dist: Add sys/serial.h.
+
+	* posix/wait.h: New file.
+	* posix/Makefile (headers): Add wait.h.
+
+Sat Nov 23 17:27:52 1996  Roland McGrath  <roland@gnu.ai.mit.edu>
+
+	* Makeconfig ($(common-objpfx)soversions.mk): Use regular
+	expression instead of shell pattern matching.
+	* shlib-versions: Change to regular expressions.
+
+Sat Nov 23 13:24:55 1996  Ulrich Drepper  <drepper@cygnus.com>
+
+	* io/stat.c: Add section from libgcc to copyright comment
+	to allow this file to be statically linked in applications.
+	* io/fstat.c: Likewise.
+	* io/lstat.c: Likewise.
+	* io/mknod.c: Likewise.
+
+Fri Nov 22 15:14:23 1996  Ulrich Drepper  <drepper@cygnus.com>
+
+	* csu/initfini.c: Add section from libgcc to copyright comment
+	to allow this file to be statically linked in applications.
+
+	* malloc/obstack.h [!_LIBC && !HAVE_STRING_H]: Define memcpy if
+	not already defined.
+	(obstack_grow, obstack_grow0): Correct placement of braces.
+
+	* gnu-versions.h (_GNU_OBSTACK_INTERFACE_VERSION): Define to 2.
+	* malloc/obstack.c (OBSTACK_INTERFACE_VERSION): Define to 2.
+
+Thu Nov 21 19:54:51 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* Makerules (make-link): Simplify by changing directory only if
+	not using rellns-sh; check whether we really have symbolic links.
+
+	* rellns-sh: Fix the case of $(dirname $2) being a prefix of
+	$(dirname $1); use status of ln for exit code; make more robust
+	against multiple slashes in a row.
+
+Thu Nov 21 13:05:21 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* configure.in (after AC_CANONICAL_HOST): mutate *-*-gnu* names
+	into *-*-gnu-gnu*.
+	* shlib-versions (gnu versions): Recognize *-*-gnu-gnu* instead of
+	the three-part name, to distinguish correctly from *-*-linux-gnu*.
+
+	* sysdeps/mach/hurd/Makefile ($(libdir)/libc.so): Depend on
+	$(rpcuserlibs).
+
+	* sysdeps/mach/hurd/Makefile (install-others): Add
+	$(libdir)/libc_p.a.
+	($(libdir)/libc_p.a): New rule.
+	* sysdeps/mach/hurd/libc_p-ldscript: New file.
+	* sysdeps/mach/hurd/Dist: Add libc_p-ldscript.
+
+Wed Nov 20 20:28:21 1996  Richard Henderson  <rth@tamu.edu>
+
+	* Makerules (make-link): Use $(shell) to find rellns-sh before we cd.
+	* time/Makefile: Likewise.
+
+	* sysdeps/alpha/elf/Makefile: New file.  Build crtbegin.o & crtend.o.
+	* sysdeps/alpha/elf/Dist: New file.
+	* sysdeps/alpha/elf/crtbegin.S, sysdeps/alpha/elf/crtend.S: New files.
+	The bits currently distributed with GCC fail in two ways -- they don't
+	understand multiple .got subsections and the extents of the lists are
+	dynamicly bound meaning that the application's lists get executed
+	multiple times and the library's lists never get executed.
+
+Wed Nov 20 00:42:45 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* stdlib/strtod.c: Fix previous change.
+
+Wed Nov 20 22:07:58 1996  Andreas Jaeger  <aj@arthur.pfalz.de>
+
+	* time/Makefile ($(installed-localtime-file)): Use $(..) to find
+	rellns-sh script.
+
+Wed Nov 20 12:50:54 1996  Ulrich Drepper  <drepper@cygnus.com>
+
+	* stdio-common/Makefile: Add CFLAGS-scanf7.c to prevent warning.
+	Likesie for scanf4.c
+
 Wed Nov 20 02:04:11 1996  Ulrich Drepper  <drepper@cygnus.com>
 
 	* sysdeps/unix/sysv/linux/sigsuspend.c: Make sigsuspend a weak
diff --git a/Makeconfig b/Makeconfig
index 0a338e12e2..1c25ace156 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -523,9 +523,10 @@ $(common-objpfx)soversions.mk: $(..)shlib-versions $(..)Makeconfig \
 	(file="$(wildcard $(patsubst %,$(..)%/shlib-versions,$(add-ons))) \
 	       $(..)shlib-versions"; \
 	 for f in $$file; do \
-	 sed 's/#.*$$//' $$f | while read conf versions; do \
-	   test -n "$$versions" || continue; \
-	   case '$(config-machine)-$(config-vendor)-$(config-os)' in $$conf)\
+	   sed 's/#.*$$//' $$f | while read conf versions; do \
+	     test -n "$$versions" && \
+	     test `expr '$(config-machine)-$(config-vendor)-$(config-os)' \
+			: "$$conf"` != 0 || continue; \
 	     for v in $$versions; do \
 	       lib=`echo $$v | sed 's/=.*$$//'`; \
 	       if eval "test -z \"\$$vers_lib$$lib\""; then \
@@ -536,9 +537,10 @@ $(common-objpfx)soversions.mk: $(..)shlib-versions $(..)Makeconfig \
 			   echo "all-sonames+=$$lib.so\$$($$lib.so-version)";;\
 		   *) echo "$$lib.so-version=$$number"; \
 		      echo "all-sonames+=\$$($$lib.so-version)";;  \
-		 esac; \
+	         esac; \
 	       fi; \
-	   done ;; esac; done; \
+	     done; \
+	   done; \
 	 done;) > $@T; exit 0
 	mv -f $@T $@
 
diff --git a/Makefile b/Makefile
index 41fe4c3536..1ab8945736 100644
--- a/Makefile
+++ b/Makefile
@@ -176,7 +176,7 @@ $(includedir)/stubs.h: subdir_install
 	else $(INSTALL_DATA) $(objpfx)stubs.h $@; fi
 	rm -f $(objpfx)stubs.h
 
-ifeq (yes, $(build-shared))
+ifeq (yes,$(build-shared))
 
 # Like stubs.h the gnu/lib-names.h header is not used while building the
 # libc itself.  So we generate it while installing.
diff --git a/Makerules b/Makerules
index 6a8638f6e9..19ec2410d8 100644
--- a/Makerules
+++ b/Makerules
@@ -600,16 +600,24 @@ versioned := $(strip $(foreach so,$(install-lib.so),\
 $(addprefix $(slibdir)/,$(filter-out $(versioned),$(install-lib.so))): \
 $(slibdir)/%.so: $(objpfx)%.so; $(do-install-program)
 
+ifneq ($(findstring -s,$(LN_S)),)
 define make-link
-here=`pwd`; cd $(@D); \
-rm -f $(@F).new; \
+rm -f $@.new; \
 if test '$(@D)' = '$(<D)'; then \
-  $(LN_S) $(<F) $(@F).new; \
+  (cd $(@D); $(LN_S) $(<F) $(@F).new); \
 else \
-  $(SHELL) $$here/$(..)rellns-sh $< $(@F).new; \
+  $(SHELL) $(..)rellns-sh $< $@.new; \
 fi; \
-mv -f $(@F).new $(@F)
+mv -f $@.new $@
+endef
+else
+# If we have no symbolic links don't bother with rellns-sh.
+define make-link
+rm -f $@.new; \
+$(LN_S) $< $@.new; \
+mv -f $@.new $@
 endef
+endif
 
 ifdef libc.so-version
 # For a library specified to be version N, install three files:
diff --git a/configure b/configure
index 8237d99090..b2586e2f57 100755
--- a/configure
+++ b/configure
@@ -2,7 +2,7 @@
 
 # From configure.in CVSid
 # Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.10.3 
+# Generated automatically using autoconf version 2.11 
 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
 #
 # This configure script is free software; the Free Software Foundation
@@ -74,6 +74,8 @@ mandir='${prefix}/man'
 # Initialize some other variables.
 subdirs=
 MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
 
 ac_prev=
 for ac_option
@@ -355,7 +357,7 @@ EOF
     verbose=yes ;;
 
   -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 2.10.3"
+    echo "configure generated by autoconf version 2.11"
     exit 0 ;;
 
   -with-* | --with-*)
@@ -702,7 +704,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:706: checking host system type" >&5
+echo "configure:708: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -722,6 +724,20 @@ host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
 host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$host" 1>&6
 
+
+# The way shlib-versions is used to generate soversions.mk uses a
+# fairly simplistic model for name recognition that can't distinguish
+# i486-pc-linux-gnu fully from i486-pc-gnu.  So we mutate a $host_os
+# of `gnu*' here to be `gnu-gnu*' just so that shlib-versions can
+# tell.  This doesn't get used much beyond that, so it's fairly safe.
+case "$host_os" in
+linux*)
+  ;;
+gnu*)
+  host_os=`echo $host_os | sed -e 's/gnu/gnu-gnu/'`
+  ;;
+esac
+
 # We keep the original values in `$config_*' and never modify them, so we
 # can write them unchanged into config.make.  Everything else uses
 # $machine, $vendor, and $os, and changes them whenever convenient.
@@ -768,7 +784,7 @@ esac
 # This can take a while to compute.
 sysdep_dir=$srcdir/sysdeps
 echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6
-echo "configure:772: checking sysdep dirs" >&5
+echo "configure:788: checking sysdep dirs" >&5
 # Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1.
 os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`"
 
@@ -969,7 +985,7 @@ echo "$ac_t""sysdeps/generic sysdeps/stub" 1>&6
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:973: checking for a BSD compatible install" >&5
+echo "configure:989: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1020,10 +1036,10 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 if test "$INSTALL" = "${srcdir}/install-sh -c"; then
   # The makefiles need to use a different form to find it in $srcdir.
-  INSTALL="$(..)./install-sh -c"
+  INSTALL='$(..)./install-sh -c'
 fi
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1027: checking whether ln -s works" >&5
+echo "configure:1043: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1048,7 +1064,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1052: checking for $ac_word" >&5
+echo "configure:1068: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1079,7 +1095,7 @@ test -n "$MSGFMT" || MSGFMT=":"
 
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1083: checking build system type" >&5
+echo "configure:1099: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -1105,7 +1121,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1109: checking for $ac_word" >&5
+echo "configure:1125: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1137,7 +1153,7 @@ if test $host != $build; then
   # Extract the first word of "gcc cc", so it can be a program name with args.
 set dummy gcc cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1141: checking for $ac_word" >&5
+echo "configure:1157: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_BUILD_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1164,7 +1180,7 @@ fi
 
 fi
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1168: checking how to run the C preprocessor" >&5
+echo "configure:1184: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1179,13 +1195,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1183 "configure"
+#line 1199 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1189: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1205: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1196,13 +1212,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1200 "configure"
+#line 1216 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1206: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1222: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1227,7 +1243,7 @@ echo "$ac_t""$CPP" 1>&6
 # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1231: checking for $ac_word" >&5
+echo "configure:1247: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1258,7 +1274,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1262: checking for $ac_word" >&5
+echo "configure:1278: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1289,7 +1305,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1293: checking for $ac_word" >&5
+echo "configure:1309: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1324,7 +1340,7 @@ fi
 # Extract the first word of "bash", so it can be a program name with args.
 set dummy bash; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1328: checking for $ac_word" >&5
+echo "configure:1344: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_BASH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1361,7 +1377,7 @@ fi
 
 
 echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:1365: checking for signed size_t type" >&5
+echo "configure:1381: checking for signed size_t type" >&5
 if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1385,12 +1401,12 @@ EOF
 fi
 
 echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:1389: checking for libc-friendly stddef.h" >&5
+echo "configure:1405: checking for libc-friendly stddef.h" >&5
 if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1394 "configure"
+#line 1410 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -1405,7 +1421,7 @@ size_t size; wchar_t wchar;
 if (&size == NULL || &wchar == NULL) abort ();
 ; return 0; }
 EOF
-if { (eval echo configure:1409: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1425: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_friendly_stddef=yes
 else
@@ -1425,7 +1441,7 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
 fi
 
 echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
-echo "configure:1429: checking whether we need to use -P to assemble .S files" >&5
+echo "configure:1445: checking whether we need to use -P to assemble .S files" >&5
 if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1448,7 +1464,7 @@ asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives."
 fi
 
 echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
-echo "configure:1452: checking for assembler global-symbol directive" >&5
+echo "configure:1468: checking for assembler global-symbol directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1478,7 +1494,7 @@ EOF
 fi
 
 echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:1482: checking for .set assembler directive" >&5
+echo "configure:1498: checking for .set assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1513,12 +1529,12 @@ fi
 
 if test $elf != yes; then
   echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:1517: checking for .init and .fini sections" >&5
+echo "configure:1533: checking for .init and .fini sections" >&5
 if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1522 "configure"
+#line 1538 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1527,7 +1543,7 @@ asm (".section .init");
 				    asm (".text");
 ; return 0; }
 EOF
-if { (eval echo configure:1531: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1547: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_have_initfini=yes
 else
@@ -1553,19 +1569,19 @@ if test $elf = yes; then
   libc_cv_asm_underscores=no
 else
   echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:1557: checking for _ prefix on C symbol names" >&5
+echo "configure:1573: checking for _ prefix on C symbol names" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1562 "configure"
+#line 1578 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:1569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1585: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
@@ -1593,7 +1609,7 @@ if test $elf = yes; then
   libc_cv_asm_weakext_directive=no
 else
   echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
-echo "configure:1597: checking for assembler .weak directive" >&5
+echo "configure:1613: checking for assembler .weak directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1616,7 +1632,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
 
 if test $libc_cv_asm_weak_directive = no; then
   echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
-echo "configure:1620: checking for assembler .weakext directive" >&5
+echo "configure:1636: checking for assembler .weakext directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1653,7 +1669,7 @@ EOF
 fi
 
 echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:1657: checking for ld --no-whole-archive" >&5
+echo "configure:1673: checking for ld --no-whole-archive" >&5
 if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1664,7 +1680,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -Wl,--no-whole-archive
-			    -o conftest conftest.c'; { (eval echo configure:1668: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c'; { (eval echo configure:1684: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_ld_no_whole_archive=yes
 else
   libc_cv_ld_no_whole_archive=no
@@ -1675,7 +1691,7 @@ fi
 echo "$ac_t""$libc_cv_ld_no_whole_archive" 1>&6
 
 echo $ac_n "checking for gcc -fno-exceptions""... $ac_c" 1>&6
-echo "configure:1679: checking for gcc -fno-exceptions" >&5
+echo "configure:1695: checking for gcc -fno-exceptions" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_no_exceptions'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1686,7 +1702,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -fno-exceptions
-			    -o conftest conftest.c'; { (eval echo configure:1690: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c'; { (eval echo configure:1706: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_no_exceptions=yes
 else
   libc_cv_gcc_no_exceptions=no
@@ -1738,7 +1754,7 @@ if test "$uname" = generic; then
   fi
 
   echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:1742: checking OS release for uname" >&5
+echo "configure:1758: checking OS release for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1760,7 +1776,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
   uname_release="$libc_cv_uname_release"
 
   echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
-echo "configure:1764: checking OS version for uname" >&5
+echo "configure:1780: checking OS version for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1782,7 +1798,7 @@ else
 fi
 
 echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:1786: checking stdio selection" >&5
+echo "configure:1802: checking stdio selection" >&5
 
 case $stdio in
 libio) cat >> confdefs.h <<\EOF
@@ -1910,7 +1926,7 @@ do
     echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
     exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
   -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 2.10.3"
+    echo "$CONFIG_STATUS generated by autoconf version 2.11"
     exit 0 ;;
   -help | --help | --hel | --he | --h)
     echo "\$ac_cs_usage"; exit 0 ;;
@@ -1999,10 +2015,10 @@ cat >> $CONFIG_STATUS <<\EOF
 
 # Split the substitutions into bite-sized pieces for seds with
 # small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
 ac_file=1 # Number of current file.
-ac_inc=90 # Lines per file.
 ac_beg=1 # First line for current file.
-ac_end=$ac_inc # Line after last line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
 ac_more_lines=:
 ac_sed_cmds=""
 while $ac_more_lines; do
@@ -2022,7 +2038,7 @@ while $ac_more_lines; do
     fi
     ac_file=`expr $ac_file + 1`
     ac_beg=$ac_end
-    ac_end=`expr $ac_end + $ac_inc`
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
   fi
 done
 if test -z "$ac_sed_cmds"; then
@@ -2154,8 +2170,6 @@ EOF
 
 # Break up conftest.vals because some shells have a limit on
 # the size of here documents, and old seds have small limits too.
-# Maximum number of lines to put in a single here document.
-ac_max_here_lines=12
 
 rm -f conftest.tail
 while :
diff --git a/configure.in b/configure.in
index ec2b5a1e3a..4a3f663cb5 100644
--- a/configure.in
+++ b/configure.in
@@ -1,6 +1,6 @@
 Dnl Process this file with autoconf to produce a configure script.
 AC_REVISION([$CVSid$])
-AC_PREREQ(2.10.2)dnl		dnl Minimum Autoconf version required.
+AC_PREREQ(2.11)dnl		dnl Minimum Autoconf version required.
 AC_INIT(features.h)
 AC_CONFIG_HEADER(config.h)
 
@@ -85,6 +85,20 @@ if test x"$add_ons" != x; then
 fi
 
 AC_CANONICAL_HOST
+
+# The way shlib-versions is used to generate soversions.mk uses a
+# fairly simplistic model for name recognition that can't distinguish
+# i486-pc-linux-gnu fully from i486-pc-gnu.  So we mutate a $host_os
+# of `gnu*' here to be `gnu-gnu*' just so that shlib-versions can
+# tell.  This doesn't get used much beyond that, so it's fairly safe.
+case "$host_os" in
+linux*)
+  ;;
+gnu*)
+  host_os=`echo $host_os | sed -e 's/gnu/gnu-gnu/'`
+  ;;
+esac
+
 # We keep the original values in `$config_*' and never modify them, so we
 # can write them unchanged into config.make.  Everything else uses
 # $machine, $vendor, and $os, and changes them whenever convenient.
@@ -332,7 +346,7 @@ AC_MSG_RESULT(sysdeps/generic sysdeps/stub)
 AC_PROG_INSTALL
 if test "$INSTALL" = "${srcdir}/install-sh -c"; then
   # The makefiles need to use a different form to find it in $srcdir.
-  INSTALL="$(..)./install-sh -c"
+  INSTALL='$(..)./install-sh -c'
 fi
 AC_PROG_LN_S
 AC_CHECK_PROGS(MSGFMT, msgfmt gmsgfmt, :)
diff --git a/csu/initfini.c b/csu/initfini.c
index f816e08169..dc78e84c2d 100644
--- a/csu/initfini.c
+++ b/csu/initfini.c
@@ -1,21 +1,30 @@
 /* Special .init and .fini section support.
-Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it
+   and/or modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Library General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Libraty General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   The GNU C Library is distributed in the hope that it will be
+   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 /* This file is compiled into assembly code which is then surrounded by the
    lines `cat > crtcommon.tmp <<\EOF_common' and `EOF_common' and thus
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index 115982f375..01e4f1974e 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -53,8 +53,9 @@ _dl_map_object_deps (struct link_map *map,
       preloads[nlist]->l_reserved = 1;
     }
 
-  /* Terminate the list.  */
+  /* Terminate the lists.  */
   head[nlist].next = NULL;
+  duphead.next = NULL;
 
   /* Start here for adding dependencies to the list.  */
   tailp = &head[nlist++];
diff --git a/gnu-versions.h b/gnu-versions.h
index 15b07999dd..6cb5c70dec 100644
--- a/gnu-versions.h
+++ b/gnu-versions.h
@@ -44,7 +44,7 @@
    remember, if any of these versions change, the libc.so major version
    number must change too (so avoid it)!  */
 
-#define _GNU_OBSTACK_INTERFACE_VERSION	1 /* vs malloc/obstack.c */
+#define _GNU_OBSTACK_INTERFACE_VERSION	2 /* vs malloc/obstack.c */
 #define _GNU_REGEX_INTERFACE_VERSION	1 /* vs posix/regex.c */
 #define _GNU_GLOB_INTERFACE_VERSION	1 /* vs posix/glob.c */
 
diff --git a/io/fstat.c b/io/fstat.c
index 60dd2f002d..63341555ad 100644
--- a/io/fstat.c
+++ b/io/fstat.c
@@ -1,20 +1,29 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Library General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Libraty General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <sys/stat.h>
 
diff --git a/io/lstat.c b/io/lstat.c
index f2ab6bc7a1..84be8f7bfd 100644
--- a/io/lstat.c
+++ b/io/lstat.c
@@ -1,20 +1,29 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Library General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Libraty General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <sys/stat.h>
 
diff --git a/io/mknod.c b/io/mknod.c
index 95ebe5a6d2..b5d51a203c 100644
--- a/io/mknod.c
+++ b/io/mknod.c
@@ -1,20 +1,30 @@
 /* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Library General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Libraty General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
 
 #include <sys/types.h>
 #include <sys/stat.h>
diff --git a/io/stat.c b/io/stat.c
index 007fdf0dd6..faadce862c 100644
--- a/io/stat.c
+++ b/io/stat.c
@@ -1,20 +1,29 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Library General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file.  (The Libraty General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <sys/stat.h>
 
diff --git a/libio/libio.h b/libio/libio.h
index 0cd6b39c24..7dd47db9fa 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -303,6 +303,9 @@ extern int _IO_vfprintf __P((_IO_FILE*, const char*, _IO_va_list));
 extern _IO_ssize_t _IO_padn __P((_IO_FILE *, int, _IO_ssize_t));
 extern _IO_size_t _IO_sgetn __P((_IO_FILE *, void*, _IO_size_t));
 
+extern _IO_fpos_t _IO_seekoff __P((_IO_FILE*, _IO_off_t, int, int));
+extern _IO_fpos_t _IO_seekpos __P((_IO_FILE*, _IO_fpos_t, int));
+
 extern void _IO_free_backup_area __P((_IO_FILE*));
 
 #ifdef __cplusplus
diff --git a/libio/strfile.h b/libio/strfile.h
index 55783bb5c1..4934a06e3c 100644
--- a/libio/strfile.h
+++ b/libio/strfile.h
@@ -1,4 +1,4 @@
-/* 
+/*
 Copyright (C) 1993 Free Software Foundation
 
 This file is part of the GNU IO Library.  This library is free
@@ -32,8 +32,6 @@ typedef void (*_IO_free_type) __P((void*));
 
 struct _IO_str_fields
 {
-  /* The current length is max(_len, _IO_write_ptr-_IO_write_base). */
-  _IO_size_t _len;
   _IO_alloc_type _allocate_buffer;
   _IO_free_type _free_buffer;
 };
diff --git a/libio/strops.c b/libio/strops.c
index 464063322d..8a6c56d055 100644
--- a/libio/strops.c
+++ b/libio/strops.c
@@ -26,7 +26,31 @@ the executable file might be covered by the GNU General Public License. */
 #include "libioP.h"
 #include <string.h>
 
-#define LEN(fp) (((_IO_strfile*)(fp))->_s._len)
+#if 0
+/* The following definitions are for exposition only.
+   They map the terminlogy used in the ANSI/ISO C++ draft standard
+   to the implementation. */
+
+/* allocated:  set  when a dynamic array object has been allocated, and
+   hence should be freed by the destructor for the strstreambuf object. */
+#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
+
+/* constant:  set when the array object has const elements,
+   so the output sequence cannot be written. */
+#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
+
+/* alsize:  the suggested minimum size for a dynamic array object. */
+#define ALSIZE(FP) ??? /* not stored */
+
+/* palloc: points to the function to call to allocate a dynamic array object.*/
+#define PALLOC(FP) \
+  ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
+
+/* pfree: points  to  the  function  to call to free a dynamic array object. */
+#define PFREE(FP) \
+  ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
+
+#endif
 
 #ifdef TODO
 /* An "unbounded buffer" is when a buffer is supplied, but with no
@@ -44,27 +68,17 @@ DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
     {
       /* If size is negative 'the characters are assumed to
 	 continue indefinitely.'  This is kind of messy ... */
-#if 1
       int s;
       size = 512;
-      /* Try increasing powers of 2, as long as we don't wrap around.
-	 This can lose in pathological cases (ptr near the end
-	 of the address space).  A better solution might be to
-	 adjust the size on underflow/overflow.  FIXME. */
-      for ( ; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
+      /* Try increasing powers of 2, as long as we don't wrap around. */
+      for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
 	size = s;
-      size = s;
-#else
-      /* The following semi-portable kludge assumes that
-	 sizeof(unsigned long) == sizeof(char*). Hence,
-	 (unsigned long)(-1) should be the largest possible address. */
-      unsigned long highest = (unsigned long)(-1);
-      /* Pointers are signed on some brain-damaged systems, in
-	 which case we divide by two to get the maximum signed address. */
-      if  ((char*)highest < ptr)
-	highest >>= 1;
-      size = (char*)highest - ptr;
-#endif
+      /* Try increasing size as much as we can without wrapping around. */
+      for (s = size >> 1; s > 0; s >>= 1)
+	{
+	  if (ptr + size + s > ptr)
+	    size += s;
+	}
     }
   _IO_setb(fp, ptr, ptr+size, 0);
 
@@ -83,7 +97,6 @@ DEFUN(_IO_str_init_static, (fp, ptr, size, pstart),
       fp->_IO_write_end = ptr;
       fp->_IO_read_end = ptr+size;
     }
-  LEN(fp) = size;
   /* A null _allocate_buffer function flags the strfile as being static. */
   (((_IO_strfile*)(fp))->_s._allocate_buffer) =  (_IO_alloc_type)0;
 }
@@ -101,34 +114,25 @@ DEFUN(_IO_str_overflow, (fp, c),
       register _IO_FILE* fp AND int c)
 {
   int flush_only = c == EOF;
-  _IO_size_t pos = fp->_IO_write_ptr - fp->_IO_write_base;
-  _IO_size_t get_pos = fp->_IO_read_ptr - fp->_IO_read_base;
+  _IO_size_t pos;
   if (fp->_flags & _IO_NO_WRITES)
       return flush_only ? 0 : EOF;
-  if (pos > LEN(fp)) LEN(fp) = pos;
   if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
     {
-      pos = get_pos;
       fp->_flags |= _IO_CURRENTLY_PUTTING;
-      get_pos = LEN(fp);
+      fp->_IO_write_ptr = fp->_IO_read_ptr;
+      fp->_IO_read_ptr = fp->_IO_read_end;
     }
-  if (pos >= (_IO_size_t) (_IO_blen(fp) + flush_only))
+  pos =  fp->_IO_write_ptr - fp->_IO_write_base;
+  if (pos >= _IO_blen(fp) + flush_only)
     {
       if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
-	{
-#ifdef TODO
-	  if (indefinite size)
-	    {
-	      fp->_IO_buf_end += 512;
-	    }
-	  else
-#endif
-	  return EOF;
-	}
+	return EOF;
       else
 	{
 	  char *new_buf;
-	  _IO_size_t new_size = 2 * _IO_blen(fp);
+	  char *old_buf = fp->_IO_buf_base;
+	  _IO_size_t new_size = 2 * _IO_blen(fp) + 100;
 	  new_buf
 	    = (char*)(*((_IO_strfile*)fp)->_s._allocate_buffer)(new_size);
 	  if (new_buf == NULL)
@@ -136,31 +140,32 @@ DEFUN(_IO_str_overflow, (fp, c),
 	      /*	  __ferror(fp) = 1; */
 	      return EOF;
 	    }
-	  memcpy(new_buf, fp->_IO_buf_base, _IO_blen(fp));
-#if 0
-	  if (lenp == &LEN(fp)) /* use '\0'-filling */
-	      memset(new_buf + pos, 0, blen() - pos);
-#endif
 	  if (fp->_IO_buf_base)
 	    {
+	      memcpy(new_buf, old_buf, _IO_blen(fp));
 	      (*((_IO_strfile*)fp)->_s._free_buffer)(fp->_IO_buf_base);
 	      /* Make sure _IO_setb won't try to delete _IO_buf_base. */
 	      fp->_IO_buf_base = NULL;
 	    }
+#if 0
+	  if (lenp == &LEN(fp)) /* use '\0'-filling */
+	      memset(new_buf + pos, 0, blen() - pos);
+#endif
 	  _IO_setb(fp, new_buf, new_buf + new_size, 1);
+	  fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf);
+	  fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf);
+	  fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf);
+	  fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf);
+
 	  fp->_IO_write_base = new_buf;
+	  fp->_IO_write_end = fp->_IO_buf_end;
 	}
-      fp->_IO_write_end = fp->_IO_buf_end;
     }
 
-  fp->_IO_write_ptr = fp->_IO_buf_base + pos;
-
-  fp->_IO_read_base = fp->_IO_buf_base;
-  fp->_IO_read_ptr = fp->_IO_buf_base + get_pos;
-  fp->_IO_read_end = fp->_IO_buf_base + LEN(fp);
-
   if (!flush_only)
     *fp->_IO_write_ptr++ = (unsigned char) c;
+  if (fp->_IO_write_ptr > fp->_IO_read_end)
+    fp->_IO_read_end = fp->_IO_write_ptr;
   return c;
 }
 
@@ -168,28 +173,29 @@ int
 DEFUN(_IO_str_underflow, (fp),
       register _IO_FILE* fp)
 {
-  _IO_size_t ppos = fp->_IO_write_ptr - fp->_IO_write_base;
-  if (ppos > LEN(fp)) LEN(fp) = ppos;
+  if (fp->_IO_write_ptr > fp->_IO_read_end)
+    fp->_IO_read_end = fp->_IO_write_ptr;
   if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
     {
       fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+      fp->_IO_read_ptr = fp->_IO_write_ptr;
       fp->_IO_write_ptr = fp->_IO_write_end;
     }
-  fp->_IO_read_end = fp->_IO_read_base + LEN(fp);
   if (fp->_IO_read_ptr < fp->_IO_read_end)
     return *fp->_IO_read_ptr;
   else
     return EOF;
 }
 
+/* The size of the valid part of the buffer.  */
+
 _IO_ssize_t
 DEFUN(_IO_str_count, (fp),
       register _IO_FILE *fp)
 {
-  _IO_ssize_t put_len = fp->_IO_write_ptr - fp->_IO_write_base;
-  if (put_len < (_IO_ssize_t) LEN(fp))
-    put_len = LEN(fp);
-  return put_len;
+  return (fp->_IO_write_ptr > fp->_IO_read_end ? fp->_IO_write_ptr
+	  : fp->_IO_read_end)
+    - fp->_IO_read_base;
 }
 
 _IO_pos_t
@@ -236,7 +242,6 @@ DEFUN(_IO_str_seekoff, (fp, offset, dir, mode),
 	}
       if (offset < 0 || (_IO_ssize_t)offset > cur_size)
 	return EOF;
-      LEN(fp) = cur_size;
       fp->_IO_write_ptr = fp->_IO_write_base + offset;
       new_pos = offset;
     }
diff --git a/login/Makefile b/login/Makefile
index 247ab958df..da47089b5a 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -12,9 +12,9 @@
 # Library General Public License for more details.
 
 # You should have received a copy of the GNU Library General Public
-# License along with the GNU C Library; see the file COPYING.LIB.  If
-# not, write to the Free Software Foundation, Inc.,
-# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# License along with the GNU C Library; see the file COPYING.LIB.  If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
 
 #
 #	Sub-makefile for login portion of the library.
@@ -24,9 +24,10 @@ subdir	:= login
 
 headers	:= utmp.h utmpbits.h lastlog.h pty.h
 
-routines := setutent endutent getutent getutid getutline pututline	\
-	    setutent_r endutent_r getutent_r getutid_r getutline_r	\
-	    pututline_r
+routines := getutent getutent_r getutid getutline getutid_r getutline_r \
+	    utmp_file utmp_db
+
+distribtue := utmp-private.h
 
 # Build the -lutil library with these extra functions.
 extra-libs      := libutil
diff --git a/login/getutent.c b/login/getutent.c
index 03b49dbf7e..e9462db18d 100644
--- a/login/getutent.c
+++ b/login/getutent.c
@@ -1,27 +1,27 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <utmp.h>
 
 
-/* The global data defined in setutent.c.  */
-extern struct utmp_data __utmp_data;
+/* Local buffer to store the result.  */
+static struct utmp buffer;
 
 
 struct utmp *
@@ -29,7 +29,7 @@ getutent (void)
 {
   struct utmp *result;
 
-  if (__getutent_r (&result, &__utmp_data) < 0)
+  if (__getutent_r (&buffer, &result) < 0)
     return NULL;
 
   return result;
diff --git a/login/getutent_r.c b/login/getutent_r.c
index e3550017f9..df9a7977ab 100644
--- a/login/getutent_r.c
+++ b/login/getutent_r.c
@@ -1,51 +1,196 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>
+   and Paul Janzen <pcj@primenet.com>, 1996.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
-#include <unistd.h>
+#include <assert.h>
+#include <db.h>
+#include <fcntl.h>
+#include <libc-lock.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <utmp.h>
+#include <gnu/lib-names.h>
+#include <sys/stat.h>
 
+#include "utmp-private.h"
+#include "../elf/link.h"
 
-int
-__getutent_r (struct utmp **utmp, struct utmp_data *utmp_data)
+
+/* The various backends we have.  */
+static int __setutent_unknown (int reset);
+static int __getutent_r_unknown (struct utmp *buffer, struct utmp **result);
+static void __pututline_unknown (const struct utmp *data);
+static void __endutent_unknown (void);
+
+
+/* We have three jump tables: unknown, db, or file.  */
+static struct utfuncs unknown_functions =
+{
+  __setutent_unknown,
+  __getutent_r_unknown,
+  NULL,
+  NULL,
+  __pututline_unknown,
+  __endutent_unknown,
+  NULL
+};
+
+/* Currently selected backend.  */
+struct utfuncs *__libc_utmp_jump_table = &unknown_functions;
+
+/* The tables from the services.  */
+extern struct utfuncs __libc_utmp_db_functions;
+extern struct utfuncs __libc_utmp_file_functions;
+
+
+/* We need to protect the opening of the file.  */
+__libc_lock_define_initialized (, __libc_utmp_lock)
+
+void
+__setutent (void)
+{
+  __libc_lock_lock (__libc_utmp_lock);
+
+  (void) (*__libc_utmp_jump_table->setutent) (1);
+
+  __libc_lock_unlock (__libc_utmp_lock);
+}
+weak_alias (__setutent, setutent)
+
+
+static int
+__setutent_unknown (int reset)
 {
-  /* Open utmp file if not already done.  */
-  if (utmp_data->ut_fd == -1)
+  /* We have to test whether it is still not decided which backend to use.  */
+  assert (__libc_utmp_jump_table == &unknown_functions);
+
+  /* See whether utmp db file exists.  */
+  if ((*__libc_utmp_db_functions.setutent) (reset))
+    __libc_utmp_jump_table = &__libc_utmp_db_functions;
+  else
     {
-      setutent_r (utmp_data);
-      if (utmp_data->ut_fd == -1)
-	return -1;
+      /* Either the db file does not exist or we have other
+	 problems.  So use the normal file.  */
+      (*__libc_utmp_file_functions.setutent) (reset);
+      __libc_utmp_jump_table = &__libc_utmp_file_functions;
     }
 
-  /* Position file correctly.  */
-  if (lseek (utmp_data->ut_fd, utmp_data->loc_utmp, SEEK_SET) == -1)
-    return -1;
+  return 0;
+}
+
 
-  /* Read the next entry.  */
-  if (read (utmp_data->ut_fd, &utmp_data->ubuf, sizeof (struct utmp))
-      != sizeof (struct utmp))
-    return -1;
+void
+__endutent (void)
+{
+  __libc_lock_lock (__libc_utmp_lock);
+
+  (*__libc_utmp_jump_table->endutent) ();
 
-  /* Update position pointer.  */
-  utmp_data->loc_utmp += sizeof (struct utmp);
+  __libc_lock_unlock (__libc_utmp_lock);
+}
+weak_alias (__endutent, endutent)
 
-  *utmp = &utmp_data->ubuf;
 
-  return 0;
+static void
+__endutent_unknown (void)
+{
+  /* Huh, how do we came here?  Nothing to do.  */
+}
+
+
+int
+__getutent_r (struct utmp *buffer, struct utmp **result)
+{
+  int retval;
+
+  __libc_lock_lock (__libc_utmp_lock);
+
+  retval = (*__libc_utmp_jump_table->getutent_r) (buffer, result);
+
+  __libc_lock_unlock (__libc_utmp_lock);
+
+  return retval;
 }
 weak_alias (__getutent_r, getutent_r)
+
+
+static int
+__getutent_r_unknown (struct utmp *buffer, struct utmp **result)
+{
+  /* It is not yet initialized.  */
+  __setutent_unknown (0);
+
+  return (*__libc_utmp_jump_table->getutent_r) (buffer, result);
+}
+
+
+void
+__pututline (const struct utmp *data)
+{
+  __libc_lock_lock (__libc_utmp_lock);
+
+  (*__libc_utmp_jump_table->pututline) (data);
+
+  __libc_lock_unlock (__libc_utmp_lock);
+}
+
+
+static void
+__pututline_unknown (const struct utmp *data)
+{
+  /* It is not yet initialized.  */
+  __setutent_unknown (0);
+
+  (*__libc_utmp_jump_table->pututline) (data);
+}
+
+
+int
+__utmpname (const char *file)
+{
+  int result = -1;
+
+  __libc_lock_lock (__libc_utmp_lock);
+
+  /* Close the old file.  */
+  (*__libc_utmp_jump_table->endutent) ();
+
+  /* Store new names.  */
+  if ((*__libc_utmp_file_functions.utmpname) (file) == 0
+      && !(*__libc_utmp_db_functions.utmpname) (file) == 0)
+    {
+      /* Try to find out whether we are supposed to work with a db
+	 file or not.  Do this by looking for the extension ".db".  */
+      const char *ext = strrchr (file, '.');
+
+      if (ext != NULL && strcmp (ext, ".db") == 0)
+	__libc_utmp_jump_table = &__libc_utmp_db_functions;
+      else
+	__libc_utmp_jump_table = &unknown_functions;
+
+      result = 0;
+    }
+
+  __libc_lock_unlock (__libc_utmp_lock);
+
+  return result;
+}
+weak_alias (__utmpname, utmpname)
diff --git a/login/getutid.c b/login/getutid.c
index 64ced6aeea..d3d3b5d068 100644
--- a/login/getutid.c
+++ b/login/getutid.c
@@ -1,27 +1,27 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <utmp.h>
 
 
-/* The global data defined in setutent.c.  */
-extern struct utmp_data __utmp_data;
+/* Local buffer to store the result.  */
+static struct utmp buffer;
 
 
 struct utmp *
@@ -29,8 +29,8 @@ getutid (const struct utmp *id)
 {
   struct utmp *result;
 
-  if (__getutid_r (id, &result, &__utmp_data) < 0)
+  if (__getutid_r (id, &buffer, &result) < 0)
     return NULL;
 
-  return (struct utmp *) result;
+  return result;
 }
diff --git a/login/getutid_r.c b/login/getutid_r.c
index 81070157a4..52b83cd862 100644
--- a/login/getutid_r.c
+++ b/login/getutid_r.c
@@ -1,35 +1,45 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>
+   and Paul Janzen <pcj@primenet.com>, 1996.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
+#include <libc-lock.h>
 #include <string.h>
 #include <unistd.h>
 #include <utmp.h>
 
+#include "utmp-private.h"
+
+
+/* We have to use the lock in getutent_r.c.  */
+__libc_lock_define (extern, __libc_utmp_lock)
+
+/* The jump table is also in getutent_r.c.  */
+extern struct utfuncs *__libc_utmp_jump_table;
+
 
-/* For implementing this function we don't use the getutent_r function
-   because we can avoid the reposition on every new entry this way.  */
 int
-__getutid_r (const struct utmp *id, struct utmp **utmp,
-	     struct utmp_data *utmp_data)
+__getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result)
 {
 #if (_HAVE_UT_ID - 0) && (_HAVE_UT_TYPE - 0)
+  int retval = -1;
+
   /* Test whether ID has any of the legal types.  */
   if (id->ut_type != RUN_LVL && id->ut_type != BOOT_TIME
       && id->ut_type != OLD_TIME && id->ut_type != NEW_TIME
@@ -38,77 +48,21 @@ __getutid_r (const struct utmp *id, struct utmp **utmp,
     /* No, using '<' and '>' for the test is not possible.  */
     {
       __set_errno (EINVAL);
+      *result = NULL;
       return -1;
     }
 
-  /* Open utmp file if not already done.  */
-  if (utmp_data->ut_fd == -1)
-    {
-      setutent_r (utmp_data);
-      if (utmp_data->ut_fd == -1)
-	return -1;
-    }
-
-  /* Position file correctly.  */
-  if (lseek (utmp_data->ut_fd, utmp_data->loc_utmp, SEEK_SET) == -1)
-    return -1;
-
-  if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME
-      || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME)
-    {
-      /* Search for next entry with type RUN_LVL, BOOT_TIME,
-	 OLD_TIME, or NEW_TIME.  */
-
-      while (1)
-	{
-	  /* Read the next entry.  */
-	  if (read (utmp_data->ut_fd, &utmp_data->ubuf, sizeof (struct utmp))
-	      != sizeof (struct utmp))
-	    {
-	      utmp_data->loc_utmp = 0; /* Mark loc_utmp invalid. */
-	      __set_errno (ESRCH);
-	      return -1;
-	    }
-
-	  /* Update position pointer.  */
-	  utmp_data->loc_utmp += sizeof (struct utmp);
+  __libc_lock_lock (__libc_utmp_lock);
 
-	  if (id->ut_type == utmp_data->ubuf.ut_type)
-	    break;
-	}
-    }
+  /* Not yet initialized.  */
+  if ((*__libc_utmp_jump_table->setutent) (0))
+    retval = (*__libc_utmp_jump_table->getutid_r) (id, buffer, result);
   else
-    {
-      /* Search for the next entry with the specified ID and with type
-	 INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS.  */
-
-      while (1)
-	{
-	  /* Read the next entry.  */
-	  if (read (utmp_data->ut_fd, &utmp_data->ubuf, sizeof (struct utmp))
-	      != sizeof (struct utmp))
-	    {
-	      utmp_data->loc_utmp = 0; /* Mark loc_utmp invalid. */
-	      __set_errno (ESRCH);
-	      return -1;
-	    }
-
-	  /* Update position pointer.  */
-	  utmp_data->loc_utmp += sizeof (struct utmp);
-
-	  if ((   utmp_data->ubuf.ut_type == INIT_PROCESS
-	       || utmp_data->ubuf.ut_type == LOGIN_PROCESS
-	       || utmp_data->ubuf.ut_type == USER_PROCESS
-	       || utmp_data->ubuf.ut_type == DEAD_PROCESS)
-	      && (strncmp (utmp_data->ubuf.ut_id, id->ut_id, sizeof id->ut_id)
-		  == 0))
-	    break;
-	}
-    }
+    *result = NULL;
 
-  *utmp = &utmp_data->ubuf;
+  __libc_lock_unlock (__libc_utmp_lock);
 
-  return 0;
+  return retval;
 #else	/* !_HAVE_UT_ID && !_HAVE_UT_TYPE */
   __set_errno (ENOSYS);
   return -1;
diff --git a/login/getutline.c b/login/getutline.c
index c21f81745b..16a02f6e89 100644
--- a/login/getutline.c
+++ b/login/getutline.c
@@ -1,27 +1,27 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <utmp.h>
 
 
-/* The global data defined in setutent.c.  */
-extern struct utmp_data __utmp_data;
+/* Local buffer to store the result.  */
+static struct utmp buffer;
 
 
 struct utmp *
@@ -29,8 +29,8 @@ getutline (const struct utmp *line)
 {
   struct utmp *result;
 
-  if (__getutline_r (line, &result, &__utmp_data) < 0)
+  if (__getutline_r (line, &buffer, &result) < 0)
     return NULL;
 
-  return (struct utmp *) result;
+  return result;
 }
diff --git a/login/getutline_r.c b/login/getutline_r.c
index e88267decb..2285248ece 100644
--- a/login/getutline_r.c
+++ b/login/getutline_r.c
@@ -1,74 +1,55 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>
+   and Paul Janzen <pcj@primenet.com>, 1996.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
+#include <libc-lock.h>
 #include <string.h>
 #include <unistd.h>
 #include <utmp.h>
 
+#include "utmp-private.h"
 
-/* For implementing this function we don't use the getutent_r function
-   because we can avoid the reposition on every new entry this way.  */
-int
-__getutline_r (const struct utmp *line, struct utmp **utmp,
-	       struct utmp_data *utmp_data)
-{
-  /* Open utmp file if not already done.  */
-  if (utmp_data->ut_fd == -1)
-    {
-      __setutent_r (utmp_data);
-      if (utmp_data->ut_fd == -1)
-	return -1;
-    }
 
-  /* Position file correctly.  */
-  if (lseek (utmp_data->ut_fd, utmp_data->loc_utmp, SEEK_SET) == -1)
-    return -1;
+/* We have to use the lock in getutent_r.c.  */
+__libc_lock_define (extern, __libc_utmp_lock)
+
+/* The jump table is also in getutent_r.c.  */
+extern struct utfuncs *__libc_utmp_jump_table;
 
-  while (1)
-    {
-      /* Read the next entry.  */
-      if (read (utmp_data->ut_fd, &utmp_data->ubuf, sizeof (struct utmp))
-	  != sizeof (struct utmp))
-	{
-	  utmp_data->loc_utmp = 0; /* Mark UTMP_DATA->ubuf invalid.  */
-	  __set_errno (ESRCH);
-	  return -1;
-	}
 
-      /* Update position pointer.  */
-      utmp_data->loc_utmp += sizeof (struct utmp);
+int
+__getutline_r (const struct utmp *line, struct utmp *buffer,
+	       struct utmp **result)
+{
+  int retval = -1;
+
+  __libc_lock_lock (__libc_utmp_lock);
 
-      if (
-#if _HAVE_UT_TYPE - 0
-	  (utmp_data->ubuf.ut_type == USER_PROCESS
-	   || utmp_data->ubuf.ut_type == LOGIN_PROCESS)
-	  &&
-#endif
-	  ! strncmp (line->ut_line, utmp_data->ubuf.ut_line,
-		     sizeof line->ut_line))
-	/* Stop if we found a user or login entry.  */
-	break;
-    }
+  /* Not yet initialized.  */
+  if ((*__libc_utmp_jump_table->setutent) (0))
+    retval = (*__libc_utmp_jump_table->getutline_r) (line, buffer, result);
+  else
+    *result = NULL;
 
-  *utmp = &utmp_data->ubuf;
+  __libc_lock_unlock (__libc_utmp_lock);
 
-  return 0;
+  return retval;
 }
 weak_alias (__getutline_r, getutline_r)
diff --git a/login/login.c b/login/login.c
index 00b176a104..7cbe8b603e 100644
--- a/login/login.c
+++ b/login/login.c
@@ -1,21 +1,21 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #include <limits.h>
@@ -43,8 +43,8 @@ tty_name (int fd, char **tty, size_t buf_len)
 	  rv = ttyname_r (fd, buf, buf_len);
 
 	  if (rv < 0 || memchr (buf, '\0', buf_len))
-	    /* We either got an error, or we succeeded and the returned name fit
-	       in the buffer.  */
+	    /* We either got an error, or we succeeded and the
+	       returned name fit in the buffer.  */
 	    break;
 
 	  /* Try again with a longer buffer.  */
@@ -68,9 +68,9 @@ tty_name (int fd, char **tty, size_t buf_len)
     }
 
   if (rv == 0)
-    *tty = buf;			/* Return buffer to the user.  */
+    *tty = buf;		/* Return buffer to the user.  */
   else if (buf != *tty)
-    free (buf);			/* Free what we malloced when returning an error.  */
+    free (buf);		/* Free what we malloced when returning an error.  */
 
   return rv;
 }
@@ -86,8 +86,8 @@ login (const struct utmp *ut)
   char *tty = _tty;
   int found_tty;
   const char *ttyp;
-  struct utmp_data data = { -1 };
   struct utmp copy = *ut;
+  struct utmp utbuf;
 
   /* Fill in those fields we supply.  */
 #if _HAVE_UT_TYPE - 0
@@ -118,26 +118,16 @@ login (const struct utmp *ut)
 	  struct utmp *old;
 
 	  /* Open UTMP file.  */
-	  setutent_r (&data);
+	  setutent ();
 
 	  /* Read the record.  */
-	  if (getutline_r (&copy, &old, &data) >= 0)
-	    {
-#if _HAVE_UT_TYPE - 0
-	      /* We have to fake the old entry because this `login'
-		 function does not fit well into the UTMP file
-		 handling scheme.  */
-	      old->ut_type = copy.ut_type;
-#endif
-	      pututline_r (&copy, &data);
-	    }
-	  else if (errno == ESRCH)
-	    /* We didn't find anything.  pututline_r will add UT at the end
-	       of the file in this case.  */
-	    pututline_r (&copy, &data);
+	  getutline_r (&copy, &utbuf, &old);
+
+	  /* Write the entry.  */
+	  pututline (&copy);
 
 	  /* Close UTMP file.  */
-	  endutent_r (&data);
+	  endutent ();
 	}
 
       if (tty != _tty)
@@ -147,23 +137,18 @@ login (const struct utmp *ut)
   /* Update the WTMP file.  Here we have to add a new entry.  */
   if (utmpname (_PATH_WTMP) != 0)
     {
+      struct utmp *up;
+
       /* Open the WTMP file.  */
-      setutent_r (&data);
+      setutent ();
 
       /* Position at end of file.  */
-      data.loc_utmp = lseek (data.ut_fd, 0, SEEK_END);
-      if (data.loc_utmp != -1)
-	{
-#if _HAVE_UT_TYPE - 0
-	  /* We have to fake the old entry because this `login'
-	     function does not fit well into the UTMP file handling
-	     scheme.  */
-	  data.ubuf.ut_type = copy.ut_type;
-#endif
-	  pututline_r (&copy, &data);
-	}
+      while (! getutent_r (&utbuf, &up));
+
+      /* Write the new entry.  */
+      pututline (&copy);
 
       /* Close WTMP file.  */
-      endutent_r (&data);
+      endutent ();
     }
 }
diff --git a/login/logout.c b/login/logout.c
index 8575512e0e..3e625486f6 100644
--- a/login/logout.c
+++ b/login/logout.c
@@ -25,8 +25,7 @@ Boston, MA 02111-1307, USA.  */
 int
 logout (const char *line)
 {
-  struct utmp_data data = { ut_fd: -1 };
-  struct utmp tmp;
+  struct utmp tmp, utbuf;
   struct utmp *ut;
   int result = 0;
 
@@ -35,7 +34,7 @@ logout (const char *line)
     return 0;
 
   /* Open UTMP file.  */
-  setutent_r (&data);
+  setutent ();
 
   /* Fill in search information.  */
 #if _HAVE_UT_TYPE - 0
@@ -44,7 +43,7 @@ logout (const char *line)
   strncpy (tmp.ut_line, line, sizeof tmp.ut_line);
 
   /* Read the record.  */
-  if (getutline_r (&tmp, &ut, &data) >= 0)
+  if (getutline_r (&tmp, &utbuf, &ut) >= 0)
     {
       /* Clear information about who & from where.  */
       bzero (ut->ut_name, sizeof ut->ut_name);
@@ -57,12 +56,12 @@ logout (const char *line)
       time (&ut->ut_time);
 #endif
 
-      if (pututline_r (ut, &data) >= 0)
+      if (pututline (ut) >= 0)
 	result = 1;
     }
 
   /* Close UTMP file.  */
-  endutent_r (&data);
+  endutent ();
 
   return result;
 }
diff --git a/login/logwtmp.c b/login/logwtmp.c
index 17c900181f..0d5e48e51f 100644
--- a/login/logwtmp.c
+++ b/login/logwtmp.c
@@ -1,21 +1,21 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #include <string.h>
diff --git a/login/utmp-private.h b/login/utmp-private.h
new file mode 100644
index 0000000000..4825ae3f6d
--- /dev/null
+++ b/login/utmp-private.h
@@ -0,0 +1,41 @@
+/* Internal definitions and declarations for UTMP functions.
+   Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>
+   and Paul Janzen <pcj@primenet.com>, 1996.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _UTMP_PRIVATE_H
+#define _UTMP_PRIVATE_H	1
+
+#include <utmp.h>
+
+/* The extra `int' argument for each function shows whether locking is
+   wanted or not.  */
+struct utfuncs
+{
+  int (*setutent) (int);
+  int (*getutent_r) (struct utmp *, struct utmp **);
+  int (*getutid_r) (const struct utmp *, struct utmp *, struct utmp **);
+  int (*getutline_r) (const struct utmp *, struct utmp *, struct utmp **);
+  struct utmp *(*pututline) (const struct utmp *);
+  void (*endutent) (void);
+  int (*utmpname) (const char *);
+
+};
+
+#endif /* utmp-private.h */
diff --git a/login/utmp.h b/login/utmp.h
index 6786190aad..87f822d9c3 100644
--- a/login/utmp.h
+++ b/login/utmp.h
@@ -58,9 +58,11 @@ extern int utmpname __P ((__const char *__file));
 extern struct utmp *getutent __P ((void));
 
 /* Rest the input stream to the beginning of the file.  */
+extern void __setutent __P ((void));
 extern void setutent __P ((void));
 
 /* Close the current open file.  */
+extern void __endutent __P ((void));
 extern void endutent __P ((void));
 
 /* Search forward from the current point in the utmp file until the
@@ -76,42 +78,19 @@ extern struct utmp *pututline __P ((__const struct utmp *__utmp_ptr));
 
 
 #ifdef	__USE_REENTRANT
-/* Define the data structure needed for the reentrant version.  */
-struct utmp_data
-{
-  int ut_fd;
-  off_t loc_utmp;
-  struct utmp ubuf;
-};
-
-
 /* Reentrant versions of the file for handling utmp files.  */
-extern int __getutent_r __P ((struct utmp **__utmp,
-			      struct utmp_data *__utmp_data));
-extern int getutent_r __P ((struct utmp **__utmp,
-			    struct utmp_data *__utmp_data));
-
-extern void __setutent_r __P ((struct utmp_data *__utmp_data));
-extern void setutent_r __P ((struct utmp_data *__utmp_data));
-
-extern void __endutent_r __P ((struct utmp_data *__utmp_data));
-extern void endutent_r __P ((struct utmp_data *__utmp_data));
+extern int __getutent_r __P ((struct utmp *__buffer, struct utmp **__result));
+extern int getutent_r __P ((struct utmp *__buffer, struct utmp **__result));
 
-extern int __getutid_r __P ((__const struct utmp *__id, struct utmp **__utmp,
-			     struct utmp_data *__utmp_data));
-extern int getutid_r __P ((__const struct utmp *__id, struct utmp **__utmp,
-			   struct utmp_data *__utmp_data));
+extern int __getutid_r __P ((__const struct utmp *__id, struct utmp *__buffer,
+			     struct utmp **__result));
+extern int getutid_r __P ((__const struct utmp *__id, struct utmp *__buffer,
+			   struct utmp **__result));
 
 extern int __getutline_r __P ((__const struct utmp *__line,
-			       struct utmp **__utmp,
-			       struct utmp_data *__utmp_data));
-extern int getutline_r __P ((__const struct utmp *__line, struct utmp **__utmp,
-			     struct utmp_data *__utmp_data));
-
-extern int __pututline_r __P ((__const struct utmp *__utmp_ptr,
-			       struct utmp_data *__utmp_data));
-extern int pututline_r __P ((__const struct utmp *__utmp_ptr,
-			     struct utmp_data *__utmp_data));
+			       struct utmp *__buffer, struct utmp **__result));
+extern int getutline_r __P ((__const struct utmp *__line,
+			     struct utmp *__buffer, struct utmp **__result));
 
 #endif	/* Use reentrant.  */
 
diff --git a/login/utmp_db.c b/login/utmp_db.c
new file mode 100644
index 0000000000..2c5baf6592
--- /dev/null
+++ b/login/utmp_db.c
@@ -0,0 +1,102 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>
+   and Paul Janzen <pcj@primenet.com>, 1996.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <assert.h>
+#include <db.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+#include <sys/stat.h>
+
+#include "utmp-private.h"
+
+
+/* This is the default name.  */
+static const char default_file_name[] = _PATH_UTMP_DB;
+
+/* Current file name.  */
+static const char *file_name = (const char *) default_file_name;
+
+/* Descriptor for database.  */
+static DB *db_fd;
+static char last_date[16];
+
+
+/* Our local functions.  */
+static int setutent_db (int reset);
+static void endutent_db (void);
+static int utmpname_db (const char *name);
+
+
+/* The jump table for the local functions.  */
+struct utfuncs __libc_utmp_db_functions =
+{
+  setutent_db,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  endutent_db,
+  utmpname_db
+};
+
+
+static int
+setutent_db (int reset)
+{
+  return 0;
+}
+
+
+static void
+endutent_db (void)
+{
+}
+
+
+static int
+utmpname_db (const char *name)
+{
+  if (strcmp (name, file_name) != 0)
+    {
+      if (strcmp (name, default_file_name) == 0)
+	{
+	  if (file_name != default_file_name)
+	    free ((char *) file_name);
+
+	  file_name = default_file_name;
+	}
+      else
+	{
+	  char *new_name = __strdup (name);
+	  if (new_name == NULL)
+	    /* Out of memory.  */
+	    return -1;
+
+	  if (file_name != default_file_name)
+	    free ((char *) file_name);
+
+	  file_name = new_name;
+	}
+    }
+  return 0;
+}
diff --git a/login/utmp_file.c b/login/utmp_file.c
new file mode 100644
index 0000000000..fff487a0a3
--- /dev/null
+++ b/login/utmp_file.c
@@ -0,0 +1,385 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>
+   and Paul Janzen <pcj@primenet.com>, 1996.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+
+#include "utmp-private.h"
+
+
+/* This is the default name.  */
+static const char default_file_name[] = _PATH_UTMP;
+
+/* Current file name.  */
+static const char *file_name = (const char *) default_file_name;
+
+/* Descriptor for the file and position.  */
+static int file_fd = INT_MIN;
+static off_t file_offset;
+
+static struct utmp last_entry;
+
+/* Functions defined here.  */
+static int setutent_file (int reset);
+static int getutent_r_file (struct utmp *buffer, struct utmp **result);
+static int getutid_r_file (const struct utmp *key, struct utmp *buffer,
+			   struct utmp **result);
+static int getutline_r_file (const struct utmp *key, struct utmp *buffer,
+			     struct utmp **result);
+static struct utmp *pututline_file (const struct utmp *data);
+static void endutent_file (void);
+static int utmpname_file (const char *name);
+
+
+/* Jump table for file functions.  */
+struct utfuncs __libc_utmp_file_functions =
+{
+  setutent_file,
+  getutent_r_file,
+  getutid_r_file,
+  getutline_r_file,
+  pututline_file,
+  endutent_file,
+  utmpname_file
+};
+
+
+static int
+setutent_file (int reset)
+{
+  if (file_fd == INT_MIN)
+    {
+      file_fd = open (file_name, O_RDWR);
+      if (file_fd == -1)
+	{
+	  /* Hhm, read-write access did not work.  Try read-only.  */
+	  file_fd = open (file_name, O_RDONLY);
+	  if (file_fd == -1)
+	    {
+	      perror (_("while opening UTMP file"));
+	      return 0;
+	    }
+	}
+      file_offset = 0;
+
+      /* Make sure the entry won't match.  */
+      last_entry.ut_type = -1;
+    }
+  else if (reset)
+    {
+      /* Remember we are at beginning of file.  */
+      file_offset = 0;
+
+      /* Make sure the entry won't match.  */
+      last_entry.ut_type = -1;
+    }
+
+  return 1;
+}
+
+
+static void
+endutent_file (void)
+{
+  if (file_fd >= 0)
+    close (file_fd);
+
+  file_fd = INT_MIN;
+}
+
+
+static int
+getutent_r_file (struct utmp *buffer, struct utmp **result)
+{
+  int nbytes;
+
+  /* Open utmp file if not already done.  */
+  if (file_fd == INT_MIN)
+    setutent_file (1);
+
+  if (file_fd == -1 || file_offset == -1l)
+    {
+      /* Not available.  */
+      *result = NULL;
+      return -1;
+    }
+
+  /* Read the next entry.  */
+  flock (file_fd, LOCK_SH);
+  nbytes = read (file_fd, &last_entry, sizeof (struct utmp));
+  flock (file_fd, LOCK_UN);
+
+  if (nbytes!= sizeof (struct utmp))
+    {
+      file_offset = -1l;
+      *result = NULL;
+      return -1;
+    }
+
+  /* Update position pointer.  */
+  file_offset += sizeof (struct utmp);
+
+  memcpy (buffer, &last_entry, sizeof (struct utmp));
+  *result = buffer;
+
+  return 0;
+}
+
+
+/* For implementing this function we don't use the getutent_r function
+   because we can avoid the reposition on every new entry this way.  */
+static int
+getutline_r_file (const struct utmp *line, struct utmp *buffer,
+		  struct utmp **result)
+{
+  if (file_fd < 0 || file_offset == -1l)
+    {
+      *result = NULL;
+      return -1;
+    }
+
+  while (1)
+    {
+      /* Read the next entry.  */
+      if (read (file_fd, &last_entry, sizeof (struct utmp))
+	  != sizeof (struct utmp))
+	{
+	  __set_errno (ESRCH);
+	  file_offset = -1l;
+	  *result = NULL;
+	  return -1;
+	}
+
+      /* Stop if we found a user or login entry.  */
+      if (
+#if _HAVE_UT_TYPE - 0
+	  (last_entry.ut_type == USER_PROCESS
+	   || last_entry.ut_type == LOGIN_PROCESS)
+	  &&
+#endif
+	  !strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line))
+	break;
+
+      file_offset += sizeof (struct utmp);
+    }
+
+  memcpy (buffer, &last_entry, sizeof (struct utmp));
+  *result = buffer;
+
+  return 0;
+}
+
+
+static int
+internal_getutid_r (const struct utmp *id, struct utmp *buffer)
+{
+  if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME
+      || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME)
+    {
+      /* Search for next entry with type RUN_LVL, BOOT_TIME,
+	 OLD_TIME, or NEW_TIME.  */
+
+      while (1)
+	{
+	  /* Read the next entry.  */
+	  if (read (file_fd, buffer, sizeof (struct utmp))
+	      != sizeof (struct utmp))
+	    {
+	      __set_errno (ESRCH);
+	      file_offset = -1l;
+	      return -1;
+	    }
+
+	  if (id->ut_type == buffer->ut_type)
+	    break;
+
+	  file_offset += sizeof (struct utmp);
+	}
+    }
+  else
+    {
+      /* Search for the next entry with the specified ID and with type
+	 INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS.  */
+
+      while (1)
+	{
+	  /* Read the next entry.  */
+	  if (read (file_fd, buffer, sizeof (struct utmp))
+	      != sizeof (struct utmp))
+	    {
+	      __set_errno (ESRCH);
+	      file_offset = -1l;
+	      return -1;
+	    }
+	  if ((   buffer->ut_type == INIT_PROCESS
+	       || buffer->ut_type == LOGIN_PROCESS
+	       || buffer->ut_type == USER_PROCESS
+	       || buffer->ut_type == DEAD_PROCESS)
+	      && strncmp (buffer->ut_id, id->ut_id, sizeof id->ut_id) == 0)
+	    break;
+
+	  file_offset += sizeof (struct utmp);
+	}
+    }
+
+  return 0;
+}
+
+
+/* For implementing this function we don't use the getutent_r function
+   because we can avoid the reposition on every new entry this way.  */
+static int
+getutid_r_file (const struct utmp *id, struct utmp *buffer,
+		struct utmp **result)
+{
+  if (file_fd < 0 || file_offset == -1l)
+    {
+      *result = NULL;
+      return -1;
+    }
+
+  if (internal_getutid_r (id, &last_entry) < 0)
+    {
+      *result = NULL;
+      return -1;
+    }
+
+  memcpy (buffer, &last_entry, sizeof (struct utmp));
+  *result = buffer;
+
+  return 0;
+}
+
+
+static struct utmp *
+pututline_file (const struct utmp *data)
+{
+  struct utmp buffer;
+  struct utmp *pbuf;
+  int found;
+
+  if (file_fd < 0)
+    /* Something went wrong.  */
+    return NULL;
+
+  /* Find the correct place to insert the data.  */
+  if (file_offset > 0)
+    found = 0;
+  else
+    if (   last_entry.ut_type == RUN_LVL
+	|| last_entry.ut_type == BOOT_TIME
+	|| last_entry.ut_type == OLD_TIME
+	|| last_entry.ut_type == NEW_TIME
+	|| ((   last_entry.ut_type == INIT_PROCESS
+	     || last_entry.ut_type == LOGIN_PROCESS
+	     || last_entry.ut_type == USER_PROCESS
+	     || last_entry.ut_type == DEAD_PROCESS)
+	    && !strncmp (last_entry.ut_id, data->ut_id, sizeof data->ut_id)))
+      found = 1;
+    else
+      found = internal_getutid_r (data, &buffer);
+
+  /* Try to lock the file.  */
+  if (flock (file_fd, LOCK_EX | LOCK_NB) < 0 && errno != ENOSYS)
+    {
+      /* Oh, oh.  The file is already locked.  Wait a bit and try again.  */
+      sleep (1);
+
+      /* This time we ignore the error.  */
+      (void) flock (file_fd, LOCK_EX | LOCK_NB);
+    }
+
+  if (found < 0)
+    {
+      /* We append the next entry.  */
+      file_offset = lseek (file_fd, 0, SEEK_END);
+      if (file_offset % sizeof (struct utmp) != 0)
+	{
+	  file_offset -= file_offset % sizeof (struct utmp);
+	  ftruncate (file_fd, file_offset);
+
+	  if (lseek (file_fd, 0, SEEK_END) < 0)
+	    {
+	      (void) flock (file_fd, LOCK_UN);
+	      return NULL;
+	    }
+	}
+    }
+  else
+    {
+      /* We replace the just read entry.  */
+      file_offset -= sizeof (struct utmp);
+      lseek (file_fd, file_offset, SEEK_SET);
+    }
+
+  /* Write the new data.  */
+  if (write (file_fd, data, sizeof (struct utmp)) != sizeof (struct utmp)
+      /* If we appended a new record this is only partially written.
+	 Remove it.  */
+      && found < 0)
+    {
+      (void) ftruncate (file_fd, file_offset);
+      pbuf = NULL;
+    }
+  else
+    pbuf = (struct utmp *) data;
+
+   /* And unlock the file.  */
+  (void) flock (file_fd, LOCK_UN);
+
+  return pbuf;
+}
+
+
+static int
+utmpname_file (const char *name)
+{
+  if (strcmp (name, file_name) != 0)
+    {
+      if (strcmp (name, default_file_name) == 0)
+	{
+	  if (file_name != default_file_name)
+	    free ((char *) file_name);
+
+	  file_name = default_file_name;
+	}
+      else
+	{
+	  char *new_name = __strdup (name);
+	  if (new_name == NULL)
+	    /* Out of memory.  */
+	    return -1;
+
+	  if (file_name != default_file_name)
+	    free ((char *) file_name);
+
+	  file_name = new_name;
+	}
+    }
+  return 0;
+}
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index 6ddfd61d8d..635023884e 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -97,7 +97,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
     {
       no_more = DB_LOOKUP_FCT (&nip, REENTRANT_NAME_STRING, (void **) &fct);
       if (no_more)
-	startp = (service_user *) -1;
+	startp = (service_user *) -1l;
       else
 	{
 	  startp = nip;
@@ -118,7 +118,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
   else
     {
       fct = start_fct;
-      no_more = (nip = startp) == (service_user *) -1;
+      no_more = (nip = startp) == (service_user *) -1l;
     }
 
   while (no_more == 0)
diff --git a/nss/getXXent_r.c b/nss/getXXent_r.c
index 6c8105c03f..1df51ab768 100644
--- a/nss/getXXent_r.c
+++ b/nss/getXXent_r.c
@@ -124,9 +124,9 @@ setup (void **fctp, const char *func_name, int all)
   if (startp == NULL)
     {
       no_more = DB_LOOKUP_FCT (&nip, func_name, fctp);
-      startp = no_more ? (service_user *) -1 : nip;
+      startp = no_more ? (service_user *) -1l : nip;
     }
-  else if (startp == (service_user *) -1)
+  else if (startp == (service_user *) -1l)
     /* No services at all.  */
     return 1;
   else
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index 8ce1e8d122..af74493c3f 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -339,10 +339,10 @@ nss_lookup_function (service_user *ni, const char *fct_name)
 
 	      if (nss_dlerror_run (do_open) != 0)
 		/* Failed to load the library.  */
-		ni->library->lib_handle = (void *) -1;
+		ni->library->lib_handle = (void *) -1l;
 	    }
 
-	  if (ni->library->lib_handle == (void *) -1)
+	  if (ni->library->lib_handle == (void *) -1l)
 	    /* Library not found => function not found.  */
 	    result = NULL;
 	  else
diff --git a/posix/Makefile b/posix/Makefile
index a2b7e57cda..fcf7cbae9e 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -25,7 +25,7 @@ headers	:= sys/utsname.h sys/times.h sys/wait.h sys/types.h unistd.h	      \
 	   glob.h regex.h wordexp.h fnmatch.h gnu/types.h getopt.h	      \
 	   posix1_lim.h posix2_lim.h posix_opt.h local_lim.h tar.h	      \
 	   utsnamelen.h confname.h waitflags.h waitstatus.h sys/unistd.h      \
-	   sched.h schedbits.h re_comp.h
+	   sched.h schedbits.h re_comp.h wait.h
 
 distribute := confstr.h
 
diff --git a/posix/sys/types.h b/posix/sys/types.h
index 26a35ee584..bbda57eee0 100644
--- a/posix/sys/types.h
+++ b/posix/sys/types.h
@@ -76,7 +76,6 @@ typedef unsigned short int ushort;
 typedef unsigned int uint;
 #endif
 
-#ifdef __USE_BSD
 /* These size-specific names are used by some of the inet code.  */
 
 #if !defined (__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7
@@ -112,7 +111,6 @@ __u_intN_t (64, __DI__);
 
 typedef int register_t __attribute__ ((__mode__ (__word__)));
 
-#endif
 
 /* Some code from BIND tests this macro to see if the types above are
    defined.  */
diff --git a/posix/wait.h b/posix/wait.h
new file mode 100644
index 0000000000..d01b81125f
--- /dev/null
+++ b/posix/wait.h
@@ -0,0 +1 @@
+#include <sys/wait.h>
diff --git a/rellns-sh b/rellns-sh
index 2df4721b00..40c4386c9c 100755
--- a/rellns-sh
+++ b/rellns-sh
@@ -28,15 +28,13 @@ case $1 in
   to=`echo $1 | sed 's%^/%%'`
 
   if test -d $2; then
-    fromname=.
-    from=`echo $2 | sed 's%/$%%'`
+    from=`echo $2 | sed 's%/*$%%'`
   else
-    fromname=`echo $2 | sed 's%.*/\([^/]*\)$%\1%'`
-    from=`echo $2 | sed "s%/*$fromname$%%"`
+    from=`echo $2 | sed 's%/*[^/]*$%%'`
   fi
 
-  case $from in
-  /*) from=`echo $from | sed 's%^/%%'` ;;
+  case "$from" in
+  /*) from=`echo $from | sed 's%^/*%%'` ;;
   ?*) from=`cd $from && pwd | sed 's%^/%%'` ;;
   *) from=`pwd | sed 's%^/%%'` ;;
   esac
@@ -47,8 +45,8 @@ case $1 in
 
     test "$preto" != "$prefrom" && break
 
-    to=`echo $to | sed 's%^[^/]*/\(.*\)$%\1%'`
-    from=`echo $from | sed 's%^[^/]*/\(.*\)$%\1%'`
+    to=`echo $to | sed 's%^[^/]*/*\(.*\)$%\1%'`
+    from=`echo $from | sed 's%^[^/]*/*\(.*\)$%\1%'`
   done
 
   while test -n "$from"; do
@@ -63,5 +61,3 @@ case $1 in
   ln -s $1 $2
   ;;
 esac
-
-exit 0
diff --git a/shlib-versions b/shlib-versions
index 58ea1f55b3..f2dbb79635 100644
--- a/shlib-versions
+++ b/shlib-versions
@@ -9,49 +9,49 @@
 # -------------		------- --------
 
 # The interface to -lm depends only on cpu, not on operating system.
-i?86-*-*		libm=6
-m68k-*-*		libm=6
-alpha-*-*		libm=6
+i.86-.*-.*		libm=6
+m68k-.*-.*		libm=6
+alpha-.*-.*		libm=6
 
 # We provide libc.so.6 for Linux kernel versions 2.0 and later.
-i?86-*-linux*		libc=6
-m68k-*-linux*		libc=6
-alpha-*-linux*		libc=6
+i.86-.*-linux.*		libc=6
+m68k-.*-linux.*		libc=6
+alpha-.*-linux.*	libc=6
 
 # libmachuser.so.1 corresponds to mach/*.defs as of Utah's UK22 release.
-*-*-gnu?*		libmachuser=1
+.*-.*-gnu-gnu.*		libmachuser=1
 
 # libhurduser.so.0.0 corresponds to hurd/*.defs as of 7 May 1996.
-*-*-gnu?*		libhurduser=0.0
+.*-.*-gnu-gnu*		libhurduser=0.0
 
 # libc.so.0.2 is for the Hurd alpha release 0.2.
-*-*-gnu?*		libc=0.2
+.*-.*-gnu-gnu*		libc=0.2
 
 # The dynamic loader also requires different names.
-i?86-*-linux*		ld=ld-linux.so.2
+i.86-.*-linux.*		ld=ld-linux.so.2
 # We use the ELF ABI standard name for the default.
-*-*-*			ld=ld.so.1
+.*-.*-.*		ld=ld.so.1
 
 # The -ldl interface (see <dlfcn.h>) is the same on all platforms.
-*-*-*			libdl=2
+.*-.*-.*		libdl=2
 
 # So far the -lutil interface is the same on all platforms, except for the
 # `struct utmp' format, which depends on libc.
-*-*-*			libutil=1
+.*-.*-.*		libutil=1
 
 # Version number 2 is used on other systems for the BIND 4.9.5 resolver
 # interface.
-*-*-*			libresolv=2
+.*-.*-.*		libresolv=2
 
 # Interface revision of nss_* modules.  This must match NSS_SHLIB_REVISION
 # in nss/nsswitch.h, which determines the library names used for service
 # names given in /etc/nsswitch.conf.
-*-*-*			libnss_files=1
-*-*-*			libnss_dns=1
-*-*-*			libnss_db=1
+.*-.*-.*		libnss_files=1
+.*-.*-.*		libnss_dns=1
+.*-.*-.*		libnss_db=1
 
 # We use libdb.so.2 for the interface in version 1.85 of the Berkeley DB code.
-*-*-*			libdb=2
+.*-.*-.*		libdb=2
 
 # This defines the shared library version numbers we will install.
-*-*-*			libcrypt=1
+.*-.*-.*		libcrypt=1
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index 920af7938f..ec7429c36e 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -12,9 +12,9 @@
 # Library General Public License for more details.
 
 # You should have received a copy of the GNU Library General Public
-# License along with the GNU C Library; see the file COPYING.LIB.  If
-# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-# Cambridge, MA 02139, USA.
+# License along with the GNU C Library; see the file COPYING.LIB.  If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
 
 #
 #	Specific makefile for stdio-common.
@@ -51,6 +51,8 @@ include ../Rules
 CFLAGS-_itoa.c = -Wno-unused
 CFLAGS-tst-printf.c = -Wno-format
 CFLAGS-tstdiomisc.c = -Wno-format
+CFLAGS-scanf4.c = -Wno-format
+CFLAGS-scanf7.c = -Wno-format
 
 ifeq ($(stdio),libio)
 ifneq (,$(filter %REENTRANT, $(defines)))
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index 8f94f3b168..e741f492c6 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -245,14 +245,16 @@ struct random_data
 
 extern int __random_r __P ((struct random_data *__buf, int32_t *__result));
 extern int random_r __P ((struct random_data *__buf, int32_t *__result));
+
 extern int __srandom_r __P ((unsigned int __seed, struct random_data *__buf));
+extern int srandom_r __P ((unsigned int __seed, struct random_data *__buf));
+
 extern int __initstate_r __P ((unsigned int __seed, __ptr_t __statebuf,
 			       size_t __statelen, struct random_data *__buf));
-extern int __setstate_r __P ((__ptr_t __statebuf, struct random_data *__buf));
-
-extern int srandom_r __P ((unsigned int __seed, struct random_data *__buf));
 extern int initstate_r __P ((unsigned int __seed, __ptr_t __statebuf,
 			     size_t __statelen, struct random_data *__buf));
+
+extern int __setstate_r __P ((__ptr_t __statebuf, struct random_data *__buf));
 extern int setstate_r __P ((__ptr_t __statebuf, struct random_data *__buf));
 #endif	/* Use reentrant.  */
 #endif	/* Use BSD.  */
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
index e1fff3dc3d..859e077b66 100644
--- a/stdlib/strtod.c
+++ b/stdlib/strtod.c
@@ -445,7 +445,8 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 
   /* If no other digit but a '0' is found the result is 0.0.
      Return current read pointer.  */
-  if ((c < L_('0') || c > L_('9')) && (wint_t) c != decimal && !TOLOWER (c))
+  if ((c < L_('0') || c > L_('9')) && (wint_t) c != decimal
+      && TOLOWER (c) != L_('e'))
     {
       tp = correctly_grouped_prefix (start_of_digits, cp, thousands, grouping);
       /* If TP is at the start of the digits, there was no correctly
diff --git a/sysdeps/alpha/elf/Dist b/sysdeps/alpha/elf/Dist
new file mode 100644
index 0000000000..3e7010182b
--- /dev/null
+++ b/sysdeps/alpha/elf/Dist
@@ -0,0 +1,2 @@
+crtbegin.S
+crtend.S
diff --git a/sysdeps/alpha/elf/crtbegin.S b/sysdeps/alpha/elf/crtbegin.S
new file mode 100644
index 0000000000..f75673e35f
--- /dev/null
+++ b/sysdeps/alpha/elf/crtbegin.S
@@ -0,0 +1,91 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+   Contributed by Richard Henderson (rth@tamu.edu)
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+/*
+ * Heads of the constructor/destructor lists.
+ */
+
+/* The __*TOR_LIST__ symbols are not global because when this file is used
+   in a shared library, we do not want the symbol to fall over to the
+   application's lists.  */
+
+.section .ctors,"aw"
+
+	.align 3
+__CTOR_LIST__:
+	.quad -1
+
+.section .dtors,"aw"
+
+	.align 3
+__DTOR_LIST__:
+	.quad -1
+
+
+/*
+ * Fragment of the ELF _fini routine that invokes our dtor cleanup.
+ */
+
+.section .fini,"ax"
+
+	/* Since the bits of the _fini function are spread across many
+	   object files, each potentially with its own GP, we must
+	   assume we need to load ours.  Further, our .fini section
+	   can easily be more than 4MB away from our .text bits so we
+	   can't use bsr.  */
+
+	br      $gp,1f
+1:	ldgp    $gp,0($gp)
+	jsr     $26,__do_global_dtors_aux
+
+	/* Must match the alignment we got from crti.o else we get
+	  zero-filled holes in our _fini function and thense SIGILL.  */
+	.align 3
+
+/*
+ * Invoke our destructors in order.
+ */
+
+.text
+
+	.align 3
+	.ent __do_global_dtors_aux
+
+__do_global_dtors_aux:
+	.frame  $sp,16,$26,0
+	/* GP already loaded in .fini */
+	lda     $sp,-16($sp)
+	stq     $9,8($sp)
+	stq     $26,0($sp)
+	.mask   (1<<26)|(1<<9), -16
+	.prologue 1
+
+	lda     $9,__DTOR_LIST__
+	br      1f
+0:	jsr     $26,($27)
+1:	ldq     $27,8($9)
+	addq    $9,8,$9
+	bne     $27,0b
+
+	ldq     $26,0($sp)
+	ldq     $9,8($sp)
+	lda     $sp,16($sp)
+	ret
+
+	.end __do_global_dtors_aux
diff --git a/sysdeps/alpha/elf/crtend.S b/sysdeps/alpha/elf/crtend.S
new file mode 100644
index 0000000000..7f51d81da1
--- /dev/null
+++ b/sysdeps/alpha/elf/crtend.S
@@ -0,0 +1,92 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+   Contributed by Richard Henderson (rth@tamu.edu)
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+
+/*
+ * Tails of the constructor/destructor lists.
+ */
+
+/* The __*TOR_END__ symbols are not global because when this file is used
+   in a shared library, we do not want the symbol to fall over to the
+   application's lists.  */
+
+.section .ctors,"aw"
+
+	.align 3
+__CTOR_END__:
+	.quad   0
+
+.section .dtors,"aw"
+
+	.align 3
+__DTOR_END__:
+	.quad   0
+
+
+/*
+ * Fragment of the ELF _init routine that invokes our ctor startup
+ */
+
+.section .init,"ax"
+
+	/* Since the bits of the _init function are spread across many
+	   object files, each potentially with its own GP, we must
+	   assume we need to load ours.  Further, our .init section
+	   can easily be more than 4MB away from our .text bits so we
+	   can't use bsr.  */
+
+	br      $gp,1f
+1:	ldgp    $gp,0($gp)
+	jsr     $26,__do_global_ctors_aux
+
+	/* Must match the alignment we got from crti.o else we get
+	   zero-filled holes in our _init function and thense SIGILL.  */
+	.align 3
+
+/*
+ * Invoke our destructors in order.
+ */
+
+.text
+
+	.align 3
+	.ent __do_global_ctors_aux
+
+__do_global_ctors_aux:
+	.frame  $sp,16,$26,0
+	/* GP already loaded in .init.  */
+	lda     $sp,-16($sp)
+	stq     $9,8($sp)
+	stq     $26,0($sp)
+	.mask   (1<<26)|(1<<9), -16
+	.prologue 1
+
+	lda     $9,__CTOR_END__
+	br      1f
+0:	jsr     $26,($27)
+1:	ldq     $27,-8($9)
+	subq    $9,8,$9
+	not     $27,$0
+	bne     $0,0b
+
+	ldq     $26,0($sp)
+	ldq     $9,8($sp)
+	lda     $sp,16($sp)
+	ret
+
+	.end __do_global_ctors_aux
diff --git a/sysdeps/generic/paths.h b/sysdeps/generic/paths.h
index a2ff426753..e5f34014a8 100644
--- a/sysdeps/generic/paths.h
+++ b/sysdeps/generic/paths.h
@@ -62,6 +62,7 @@
 #define	_PATH_TTY	"/dev/tty"
 #define	_PATH_UNIX	"/vmunix"
 #define	_PATH_UTMP	"/var/run/utmp"
+#define	_PATH_UTMP_DB	"/var/run/utmp.db"
 #define	_PATH_VI	"/usr/bin/vi"
 #define	_PATH_WTMP	"/var/log/wtmp"
 
diff --git a/sysdeps/generic/pty.c b/sysdeps/generic/pty.c
index 8df8aba4ba..660602b25a 100644
--- a/sysdeps/generic/pty.c
+++ b/sysdeps/generic/pty.c
@@ -59,9 +59,12 @@ openpty(amaster, aslave, name, termp, winp)
 	static char line[] = "/dev/ptyXX";
 	register const char *cp1, *cp2;
 	register int master, slave, ttygid;
+	size_t buflen = sysconf (_SC_GETGR_R_SIZE_MAX);
+	char buffer[buflen];
+	struct group grbuffer;
 	struct group *gr;
 
-	if ((gr = getgrnam("tty")) != NULL)
+	if (getgrnam_r("tty", &grbuffer, buffer, buflen, &gr) >= 0)
 		ttygid = gr->gr_gid;
 	else
 		ttygid = -1;
diff --git a/sysdeps/gnu/utmpbits.h b/sysdeps/gnu/utmpbits.h
index 37e4fb9acc..5bb230b243 100644
--- a/sysdeps/gnu/utmpbits.h
+++ b/sysdeps/gnu/utmpbits.h
@@ -52,6 +52,31 @@ struct lastlog
   char ll_host[UT_HOSTSIZE];
 };
 
+
+/* Which program created the record.  */
+enum utlogin
+{
+  unknown,
+  X,
+  local,
+  rlogin,
+  telnet,
+  rsh,
+  ftp,
+  screen,
+  splitvt,
+  xterm
+  /* More could be added here.  */
+};
+
+
+struct exit_status
+{
+  short int e_termination;	/* Process termination status.  */
+  short int e_exit;		/* Process exit status.  */
+};
+
+
 struct utmp
 {
   short int ut_type;		/* Type of login.  */
@@ -61,11 +86,14 @@ struct utmp
   char ut_user[UT_NAMESIZE];	/* Username (not NUL terminated).  */
 #define ut_name	ut_user		/* Compatible field name for same.  */
   char ut_host[UT_HOSTSIZE];	/* Hostname for remote login.  */
-  int ut_exit;			/* Process termination/exit status.  */
+  struct exit_status ut_exit;	/* The exit status of a process marked
+				   as DEAD_PROCESS.  */
   long ut_session;		/* Session ID, used for windowing.  */
   struct timeval ut_tv;		/* Time entry was made.  */
-  int32_t ut_addr;		/* Internet address of remote host.  */
-  char pad[32];			/* Reserved for future use.  */
+  int32_t ut_addr[4];		/* Internet address of remote host.  */
+  enum utlogin ut_login;	/* To store information about source.  */
+  short int ut_syslen;		/* Significant length of ut_host.  */
+  char pad[14];			/* Reserved for future use.  */
 };
 
 #define ut_time	ut_tv.tv_sec	/* Backwards compatibility.  */
diff --git a/sysdeps/mach/hurd/Dist b/sysdeps/mach/hurd/Dist
index 986efc4e2d..62fe4d96c6 100644
--- a/sysdeps/mach/hurd/Dist
+++ b/sysdeps/mach/hurd/Dist
@@ -1,3 +1,3 @@
 errnos.awk err_hurd.sub
 libc-ldscript
-
+libc_p-ldscript
diff --git a/sysdeps/mach/hurd/Makefile b/sysdeps/mach/hurd/Makefile
index 74ceb2e6e1..eb3dc01252 100644
--- a/sysdeps/mach/hurd/Makefile
+++ b/sysdeps/mach/hurd/Makefile
@@ -98,17 +98,20 @@ common-generated += errnos.d stamp-errnos
 libc-name = crt
 
 ifeq (,$(subdir))
-install-others += $(libdir)/libc.a
+install-others += $(libdir)/libc.a $(libdir)/libc_p.a
 $(libdir)/libc.a: $(hurd)/libc-ldscript; $(do-install)
+$(libdir)/libc_p.a: $(hurd)/libc_p-ldscript; $(do-install)
 endif
 
-# For the shared library, we don't need to do the linker script machination.
-# Instead, we specify the required libraries when building the shared object.
+# Make sure these are used to build the libc.so shared object too.
 rpcuserlibs := $(common-objpfx)mach/libmachuser.so \
 	       $(common-objpfx)hurd/libhurduser.so
 $(common-objpfx)libc.so: $(rpcuserlibs)
 rpath-link := $(rpath-link):$(common-objpfx)mach:$(common-objpfx)hurd
 
+# And get them into the libc.so ldscript.
+$(libdir)/libc.so: $(rpcuserlibs)
+
 # The RPC stubs from these libraries are needed in building the dynamic
 # linker, too.  It must be self-contained, so we link the needed PIC
 # objects directly into the shared object.
diff --git a/sysdeps/mach/hurd/libc_p-ldscript b/sysdeps/mach/hurd/libc_p-ldscript
new file mode 100644
index 0000000000..d809998a1f
--- /dev/null
+++ b/sysdeps/mach/hurd/libc_p-ldscript
@@ -0,0 +1,5 @@
+/* This linker script is installed as /lib/libc_p.a.
+   It makes -lc_p become just like -( -lcrt_p -lmachuser_p -lhurduser_p -).
+   */
+
+GROUP ( libcrt_p.a libmachuser_p.a libhurduser_p.a )
diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
index 825599f370..5f3f628fb5 100644
--- a/sysdeps/posix/getcwd.c
+++ b/sysdeps/posix/getcwd.c
@@ -344,8 +344,11 @@ __getcwd (buf, size)
 		      __set_errno (ENOMEM);/* closedir might have changed it.*/
 		      return NULL;
 		    }
-		  pathp = &buf[pathp - path];
+		  pathp = &buf[pathp - path + size / 2];
 		  path = buf;
+		  /* Move current contents up to the end of the buffer.
+		     This is guaranteed to be non-overlapping.  */
+		  memcpy (pathp, pathp - size / 2, path + size - pathp);
 		}
 	    }
 	  pathp -= namlen;
diff --git a/sysdeps/stub/getlogin.c b/sysdeps/stub/getlogin.c
index 484c159855..34acbc38a9 100644
--- a/sysdeps/stub/getlogin.c
+++ b/sysdeps/stub/getlogin.c
@@ -1,20 +1,20 @@
 /* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   This file is part of the GNU C Library.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <stddef.h>
 #include <errno.h>
@@ -23,11 +23,10 @@ Cambridge, MA 02139, USA.  */
 /* Return the login name of the user, or NULL if it can't be determined.
    The returned pointer, if not NULL, is good only until the next call.  */
 char *
-getlogin ()
+getlogin (void)
 {
   __set_errno (ENOSYS);
   return NULL;
 }
 
-
 stub_warning (getlogin)
diff --git a/sysdeps/stub/getlogin_r.c b/sysdeps/stub/getlogin_r.c
index fa9bb75d41..d811818096 100644
--- a/sysdeps/stub/getlogin_r.c
+++ b/sysdeps/stub/getlogin_r.c
@@ -1,21 +1,21 @@
 /* Reentrant function to return the current login name.  Stub version.
-Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #include <unistd.h>
diff --git a/sysdeps/unix/getlogin.c b/sysdeps/unix/getlogin.c
index ef985f2d2f..6e8a9a2a87 100644
--- a/sysdeps/unix/getlogin.c
+++ b/sysdeps/unix/getlogin.c
@@ -1,20 +1,20 @@
 /* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   This file is part of the GNU C Library.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #include <unistd.h>
@@ -34,9 +34,8 @@ getlogin (void)
   char tty_pathname[2 + 2 * NAME_MAX];
   char *real_tty_path = tty_pathname;
   char *result = NULL;
-  struct utmp_data utmp_data = { ut_fd: -1 };
   static char name[UT_NAMESIZE + 1];
-  struct utmp *ut, line;
+  struct utmp *ut, line, buffer;
 
   /* Get name of tty connected to fd 0.  Return NULL if not a tty or
      if fd 0 isn't open.  Note that a lot of documentation says that
@@ -52,9 +51,9 @@ getlogin (void)
 
   real_tty_path += 5;		/* Remove "/dev/".  */
 
-  __setutent_r (&utmp_data);
+  __setutent ();
   strncpy (line.ut_line, real_tty_path, sizeof line.ut_line);
-  if (__getutline_r (&line, &ut, &utmp_data) < 0)
+  if (__getutline_r (&line, &buffer, &ut) < 0)
     {
       if (errno == ESRCH)
 	/* The caller expects ENOENT if nothing is found.  */
@@ -68,7 +67,7 @@ getlogin (void)
       result = name;
     }
 
-  __endutent_r (&utmp_data);
+  __endutent ();
 
   return result;
 }
diff --git a/sysdeps/unix/getlogin_r.c b/sysdeps/unix/getlogin_r.c
index aa2c0617e6..868fdbee12 100644
--- a/sysdeps/unix/getlogin_r.c
+++ b/sysdeps/unix/getlogin_r.c
@@ -1,21 +1,21 @@
 /* Reentrant function to return the current login name.  Unix version.
-Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
 
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
 
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
 #include <unistd.h>
@@ -38,8 +38,7 @@ getlogin_r (name, name_len)
   char tty_pathname[2 + 2 * NAME_MAX];
   char *real_tty_path = tty_pathname;
   int result = 0;
-  struct utmp_data utmp_data;
-  struct utmp *ut, line;
+  struct utmp *ut, line, buffer;
 
   {
     int err;
@@ -60,9 +59,9 @@ getlogin_r (name, name_len)
 
   real_tty_path += 5;		/* Remove "/dev/".  */
 
-  setutent_r (&utmp_data);
+  __setutent ();
   strncpy (line.ut_line, real_tty_path, sizeof line.ut_line);
-  if (getutline_r (&line, &ut, &utmp_data) < 0)
+  if (__getutline_r (&line, &buffer, &ut) < 0)
     {
       if (errno == ESRCH)
 	/* The caller expects ENOENT if nothing is found.  */
@@ -85,7 +84,7 @@ getlogin_r (name, name_len)
 	  result = 0;
 	}
     }
-  endutent_r (&utmp_data);
+  __endutent ();
 
   return result;
 }
diff --git a/sysdeps/unix/sysv/linux/Dist b/sysdeps/unix/sysv/linux/Dist
index ce55ab2d25..e1a89711e2 100644
--- a/sysdeps/unix/sysv/linux/Dist
+++ b/sysdeps/unix/sysv/linux/Dist
@@ -20,6 +20,7 @@ sys/mount.h
 sys/mtio.h
 sys/procfs.h
 sys/quota.h
+sys/serial.h
 sys/socketcall.h
 sys/soundcard.h
 sys/sysctl.h
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index fcfb76c08f..69c207a575 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -8,7 +8,8 @@ sysdep_routines += sysctl clone
 sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h sys/mtio.h \
 		  sys/module.h sys/io.h sys/klog.h sys/kdaemon.h \
 		  sys/user.h syscall-list.h sys/sysmacros.h sys/procfs.h \
-		  sys/debugreg.h sys/kd.h sys/soundcard.h sys/vt.h
+		  sys/debugreg.h sys/kd.h sys/soundcard.h sys/vt.h \
+		  sys/serial.h
 
 # Generate the list of SYS_* macros for the system calls (__NR_* macros).
 $(objpfx)syscall-%.h $(objpfx)syscall-%.d: ../sysdeps/unix/sysv/linux/syscall.h
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index 6751c0d4a9..eaa6aa632f 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -62,6 +62,7 @@
 #define	_PATH_TTY	"/dev/tty"
 #define	_PATH_UNIX	"/vmlinux"
 #define _PATH_UTMP	"/var/run/utmp"
+#define _PATH_UTMP_DB	"/var/run/utmp.db"
 #define	_PATH_VI	"/usr/bin/vi"
 #define _PATH_WTMP	"/var/log/wtmp"
 
diff --git a/sysdeps/unix/sysv/linux/sys/serial.h b/sysdeps/unix/sysv/linux/sys/serial.h
new file mode 100644
index 0000000000..1844ef6032
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sys/serial.h
@@ -0,0 +1,110 @@
+/* Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _SYS_SERIAL_H
+#define _SYS_SERIAL_H	1
+/* Defines for PC AT serial port.  */
+
+/* Serial port addresses and IRQs.  */
+#define PORT_0		0x03F8
+#define PORT_1		0x02F8
+#define IRQ_0		0x04
+#define IRQ_1		0x03
+
+/* Definitions for INS8250 / 16550 chips.  */
+
+/* Defined as offsets from the port address (data port).  */
+#define DAT	0	/* Receive/transmit data.  */
+#define ICR	1	/* Interrupt control register.  */
+#define ISR	2	/* Interrupt status register.  */
+#define LCR	3	/* Line control register.  */
+#define MCR	4	/* Modem control register.  */
+#define LSR	5	/* Line status register.  */
+#define MSR	6	/* Modem status register.  */
+#define DLL	0	/* Divisor latch (lsb).  */
+#define DLH	1	/* Divisor latch (msb).  */
+
+
+/* ICR.  */
+#define RIEN	0x01	/* Enable receiver interrupt.  */
+#define TIEN	0x02	/* Enable transmitter interrupt.  */
+#define SIEN	0x04	/* Enable receiver line status interrupt.  */
+#define MIEN	0x08	/* Enable modem status interrupt.  */
+
+
+/* ISR */
+#define FFTMOUT	0x0c	/* Fifo rcvr timeout.  */
+#define RSTATUS	0x06	/* Change in receiver line status.  */
+#define RxRDY	0x04	/* Receiver data available.  */
+#define TxRDY	0x02	/* Transmitter holding register empty.  */
+#define MSTATUS	0x00	/* Change in modem status.  */
+
+
+/* LCR 3
+   Number of data bits per received/transmitted character.  */
+#define RXLEN	0x03
+#define STOP1	0x00
+#define STOP2	0x04
+#define PAREN	0x08
+#define PAREVN	0x10
+#define PARMARK	0x20
+#define SNDBRK	0x40
+#define DLAB	0x80
+
+/* Baud rate definitions.  */
+#define ASY9600	12
+
+/* Definitions for character length (data bits) in RXLEN field.  */
+#define BITS5	0x00
+#define BITS6	0x01
+#define BITS7	0x02
+#define BITS8	0x03
+
+/* MCR.  */
+#define DTR	0x01	/* Bring up DTR.  */
+#define RTS	0x02	/* Bring up RTS.  */
+#define OUT1	0x04
+#define OUT2	0x08
+#define LOOP	0x10	/* Put chip into loopback state.  */
+
+
+/* LSR */
+#define RCA	0x01	/* Receive char available.  */
+#define OVRRUN	0x02	/* Receive overrun.  */
+#define PARERR	0x04	/* Parity error.  */
+#define FRMERR	0x08	/* Framing/CRC error.  */
+#define BRKDET	0x10	/* Break detected (null char + frame error).  */
+#define XHRE	0x20	/* Transmit holding register empty.  */
+#define XSRE	0x40	/* Transmit shift register empty.  */
+
+
+/* MSR */
+#define DCTS	0x01	/* CTS has changed state.  */
+#define DDSR	0x02	/* DSR has changed state.  */
+#define DRI	0x04	/* RI has changed state.  */
+#define DDCD	0x08    /* DCD has changed state.  */
+#define CTS	0x10	/* State of CTS.  */
+#define DSR	0x20	/* State of DSR.  */
+#define RI      0x40    /* State of RI.  */
+#define DCD     0x80    /* State of DCD.  */
+
+
+#define DELTAS(x)	((x) & (DCTS | DDSR | DRI | DDCD))
+#define STATES(x)	((x) (CTS | DSR | RI | DCD))
+
+#endif /* sys/serial.h */
diff --git a/time/Makefile b/time/Makefile
index 772461c778..252b335c9e 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -125,7 +125,7 @@ $(installed-localtime-file): $(zonedir)/$(localtime) $(objpfx)zic
 	  echo Site timezone NOT reset to Factory.; \
 	else \
 	  rm -f $@T; \
-	  $(SHELL) $(top_absdir)/rellns-sh $< $@T; \
+	  $(SHELL) $(..)/rellns-sh $< $@T; \
 	  mv -f $@T $@; \
 	fi
 endif
diff --git a/time/africa b/time/africa
index a3a28c95ea..49f39fbfab 100644
--- a/time/africa
+++ b/time/africa
@@ -1,15 +1,23 @@
-# @(#)africa	7.15
+# @(#)africa	7.16
 
 # 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-09-03):
+# From Paul Eggert <eggert@twinsun.com> (1996-11-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.
+#
+# Gwillim Law <LAW@encmail.encompass.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.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
@@ -255,12 +263,17 @@ 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	max	-	Oct	 1	3:00	0	-
+Rule	Egypt	1966	1990	-	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	max	-	May	 1	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	-
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
 			2:00	Egypt	EE%sT
@@ -390,15 +403,15 @@ 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
-# From Paul Eggert <eggert@twinsun.com> (1995-12-19):
-# usno1995 (from OAG) says Libya uses 2:00 all year, as they did before 1982.
-# We don't know when they switched back.  We'll guess 1991.
 			1:00	Libya	CE%sT	1991
-			2:00	-	EET
+			2:00	-	EET	1996 Mar 30 3:00
+			1:00	Libya	CE%sT
 
 # Madagascar
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -442,7 +455,7 @@ Zone	Indian/Mayotte	3:00:56 -	LMT	1911 Jul	# Mamoutzou
 			3:00	-	EAT
 
 # Morocco
-# rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# 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	-
 Rule	Morocco	1940	only	-	Feb	25	 0:00	1:00	S
@@ -474,12 +487,15 @@ Zone	Africa/Maputo	2:10:20 -	LMT	1903 Mar
 			2:00	-	SAT
 
 # Namibia
+# 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	1:00	SAST	1943 Mar 21 2:00
-			2:00	-	SAT
+			2:00	Namibia	SA%sT
 
 # Niger
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -618,10 +634,9 @@ Rule	Tunisia	1977	only	-	Sep	24	 0:00s	0	-
 Rule	Tunisia	1978	only	-	May	 1	 0:00s	1:00	S
 Rule	Tunisia	1978	only	-	Oct	 1	 0:00s	0	-
 Rule	Tunisia	1988	only	-	Jun	 1	 0:00s	1:00	S
-Rule	Tunisia	1988	max	-	Sep	lastSun	 0:00s	0	-
+Rule	Tunisia	1988	1990	-	Sep	lastSun	 0:00s	0	-
 Rule	Tunisia	1989	only	-	Mar	26	 0:00s	1:00	S
 Rule	Tunisia	1990	only	-	May	 1	 0:00s	1:00	S
-Rule	Tunisia	1991	max	-	Mar	lastSun	 0:00s	1:00	S
 # Shanks gives 0:09 for Paris Mean Time; go with Howse's more precise 0:09:21.
 # Shanks says the 1911 switch occurred on Mar 9; go with Howse's Mar 11.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
diff --git a/time/antarctica b/time/antarctica
index 0c78eb6826..b4a7d397a3 100644
--- a/time/antarctica
+++ b/time/antarctica
@@ -1,4 +1,4 @@
-# @(#)antarctica	7.4
+# @(#)antarctica	7.5
 
 # From Paul Eggert (1996-09-03):
 # To keep things manageable, we list only locations occupied year-round;
@@ -8,6 +8,20 @@
 # I made up all time zone abbreviations mentioned here; corrections welcome!
 # FORMAT is `___' and GMTOFF is 0 for locations while uninhabited.
 
+# These rules are stolen from the `southamerica' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	ArgAQ	1964	1966	-	Mar	 1	0:00	0	-
+Rule	ArgAQ	1964	1966	-	Oct	15	0:00	1:00	S
+Rule	ArgAQ	1967	only	-	Apr	 1	0:00	0	-
+Rule	ArgAQ	1967	1968	-	Oct	Sun<=7	0:00	1:00	S
+Rule	ArgAQ	1968	1969	-	Apr	Sun<=7	0:00	0	-
+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	-
+
 
 # Argentina - 6 year-round bases
 # General Belgrano II
@@ -118,7 +132,21 @@ Rule	NZAQ	1990	max	-	Mar	Sun>=15	2:00s	0	S
 
 # USA - year-round bases
 #
-# Palmer, Anvers Island
+# Palmer, Anvers Island, since 1965 (moved 2 miles in 1968)
+#
+# From Ethan Dicks <erd@mcmsun5.mcmurdo.gov> (1996-10-06):
+# It keeps the same time as Punta Arenas, Chile, because, just like us
+# and the South Pole, that's the other end of their supply line....
+# I verified with someone who was there that since 1980,
+# Palmer has followed Chile.  Prior to that, before the Falklands War,
+# Palmer used to be supplied from Argentina.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Palmer	0	-	___	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
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
diff --git a/time/asia b/time/asia
index b5220f3915..7afe922bf4 100644
--- a/time/asia
+++ b/time/asia
@@ -1,16 +1,25 @@
-# @(#)asia	7.25
+# @(#)asia	7.26
 
 # 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> (1995-07-24):
+# From Paul Eggert <eggert@twinsun.com> (1996-11-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.
 #
+# Gwillim Law <LAW@encmail.encompass.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.
+#
 # 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.
@@ -24,7 +33,6 @@
 # Corrections are welcome!
 #		std dst
 #		LMT	Local Mean Time
-#		LST	Local Star Time (Russian ``mestnoe zvezdnoe vremya'')
 #	2:00	EET EEST Eastern European Time
 #	2:00	IST IDT	Israel
 #	3:00	AST ADT	Arabia*
@@ -48,12 +56,22 @@
 
 ###############################################################################
 
-# These rules for Russia are stolen from the `europe' file.
+# These rules are stolen from the `europe' file.
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
-Rule RussiaAsia 1981	1984	-	Apr	1	0:00	1:00	S
-Rule RussiaAsia 1981	1983	-	Oct	1	0:00	0	-
-Rule RussiaAsia 1984	max	-	Sep	lastSun	2:00s	0	-
-Rule RussiaAsia 1985	max	-	Mar	lastSun	2:00s	1:00	S
+Rule	EUAsia	1981	max	-	Mar	lastSun	 1:00u	1:00	S
+Rule	EUAsia	1996	max	-	Oct	lastSun	 1:00u	0	-
+Rule E-EurAsia	1981	max	-	Mar	lastSun	 0:00	1:00	S
+Rule E-EurAsia	1979	1995	-	Sep	lastSun	 0:00	0	-
+Rule E-EurAsia	1996	max	-	Oct	lastSun	 0:00	0	-
+Rule RussiaAsia	1981	1984	-	Apr	1	 0:00	1:00	S
+Rule RussiaAsia	1981	1983	-	Oct	1	 0:00	0	-
+Rule RussiaAsia	1984	1991	-	Sep	lastSun	 2:00s	0	-
+Rule RussiaAsia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
+Rule RussiaAsia	1992	only	-	Mar	lastSat	23:00	1:00	S
+Rule RussiaAsia	1992	only	-	Sep	lastSat	23:00	0	-
+Rule RussiaAsia	1993	max	-	Mar	lastSun	 2:00s	1:00	S
+Rule RussiaAsia	1993	1995	-	Sep	lastSun	 2:00s	0	-
+Rule RussiaAsia	1996	max	-	Oct	lastSun	 2:00s	0	-
 
 # Afghanistan
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -85,10 +103,9 @@ Zone	Asia/Baku	3:19:24 -	LMT	1924 May  2
 			3:00	-	BAKT	1957 Mar    # Baku Time
 			4:00 RussiaAsia BAK%sT	1991 Mar 31 2:00s
 			3:00	1:00	BAKST	1991 Aug 30 # independence
-			3:00 RussiaAsia	AZ%sT	1992	    # Azerbaijan Time
-			3:00	-	AZT
-# Shanks has Baku using Russian DST rules after 1991,
-# but usno1995 has Azerbaijan with no DST.  Guess no DST after 1991.
+			3:00 RussiaAsia	AZ%sT	1992 Sep lastSun 2:00s
+			4:00	-	AZT	1996 # Azerbaijan time
+			4:00	EUAsia	AZ%sT
 
 # Bahrain
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -287,18 +304,20 @@ Zone	Asia/Nicosia	2:13:28 -	LMT	1921 Nov 14
 # an MP who went on a hunger strike for 11 days to force discussion about it!
 # We have no details, but we'll guess they didn't move the clocks back in fall.
 #
-# From Paul Eggert (1995-11-13):
-# usno1995 has Georgia at 4:00.  Guess that Georgia stopped transitions
-# after spring 1994 (thus sticking at 4:00).
-# Most likely we're still missing some rule changes between 1991 and 1994.
+# From Mathew Englander <mathew@io.org>, quoting AP (1996-10-23 13:05-04):
+# Instead of putting back clocks at the end of October, Georgia
+# will stay on daylight savings time this winter to save energy,
+# President Eduard Shevardnadze decreed Wednesday.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Tbilisi	2:59:16 -	LMT	1880
 			2:59:16	-	TBMT	1924 May  2 # Tbilisi Mean Time
 			3:00	-	TBIT	1957 Mar    # Tbilisi Time
 			4:00 RussiaAsia TBI%sT	1991 Mar 31 2:00s
 			3:00	1:00	TBIST	1991 Apr  9 # independence
-			3:00 RussiaAsia GE%sT	1994 Sep 25 2:00s # Georgia Time
-			4:00	-	GET
+			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
 
 # India
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -340,6 +359,13 @@ Rule	Iran	1978	1980	-	Mar	21	0:00	1:00	S
 Rule	Iran	1978	only	-	Oct	21	0:00	0	-
 Rule	Iran	1979	only	-	Sep	19	0:00	0	-
 Rule	Iran	1980	only	-	Sep	23	0:00	0	-
+Rule	Iran	1991	only	-	May	 3	0:00s	1:00	S
+Rule	Iran	1991	only	-	Sep	20	0:00s	0	-
+Rule	Iran	1992	only	-	Mar	22	0:00	1:00	S
+Rule	Iran	1992	1993	-	Sep	23	0:00	0	-
+Rule	Iran	1993	max	-	Mar	21	0:00	1:00	S
+Rule	Iran	1994	1995	-	Sep	22	0:00	0	-
+Rule	Iran	1996	max	-	Sep	21	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Tehran	3:25:44	-	LMT	1916
 			3:25:44	-	TMT	1946	# Tehran Mean Time
@@ -353,8 +379,11 @@ Rule	Iraq	1982	only	-	May	1	0:00	1:00	D
 Rule	Iraq	1982	1984	-	Oct	1	0:00	0	S
 Rule	Iraq	1983	only	-	Mar	31	0:00	1:00	D
 Rule	Iraq	1984	1985	-	Apr	1	0:00	1:00	D
-Rule	Iraq	1985	max	-	Sep	lastSun	1:00s	0	S
-Rule	Iraq	1986	max	-	Mar	lastSun	1:00s	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.
+Rule	Iraq	1991	max	-	Apr	 1	3:00s	1:00	D
+Rule	Iraq	1991	max	-	Oct	 1	3:00s	0	D
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Baghdad	2:57:40	-	LMT	1890
 			2:57:36	-	BMT	1918	    # Baghdad Mean Time?
@@ -512,9 +541,6 @@ Zone	Asia/Ishigaki	8:16:36	-	LMT	1896
 # Other Japanese possessions are probably like Asia/Tokyo.
 
 # Jordan
-# From Paul Eggert <eggert@twinsun.com> (1993-11-18):
-# Most likely Shanks is merely guessing dates from 1992 on.
-# From Shanks (1991):
 # 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	-
@@ -529,40 +555,56 @@ 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	19	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	max	-	Apr	Fri>=1	0:00	1:00	S
-Rule    Jordan	1992	max	-	Oct	Fri>=1	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	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Amman	2:23:44 -	LMT	1931
 			2:00	Jordan	EE%sT
 
 # Kazakhstan
-# From Paul Eggert (1996-04-19):
+# From Paul Eggert (1996-11-22):
 # Andrew Evtichov <evti@chevron.com> (1996-04-13) writes that Kazakhstan
-# stayed in sync with Moscow after 1990, and that Aktau is the biggest city
-# in western Kazakhstan.  Follow Shanks before 1991, Evtichov afterwards.
+# stayed in sync with Moscow after 1990, and that Aqtobe (formerly Aktyubinsk)
+# and Aqtau (formerly Shevchenko) are the largest cities in their zones.
+# Guess that Aqtau and Aqtobe diverged in 1995, since that's the first time
+# 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
 			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
 			5:00	-	ALMT	1992 Jan 19 2:00s
-			6:00 RussiaAsia ALM%sT
-Zone	Asia/Aktau	3:21:04	-	LMT	1924 May  2 # or Aqtau
+			6:00 E-EurAsia	ALM%sT
+Zone	Asia/Aqtobe	3:48:40	-	LMT	1924 May  2
+			4:00	-	AKT	1957 Mar # Aktyubinsk Time
+			5:00 RussiaAsia AK%sT	1991 Mar 31 2:00s
+			4:00	1:00	AKTST	1991 Sep 29 2:00s
+			4:00	-	AQTT	1992 Jan 19 2:00s # Aqtobe Time
+			5:00 E-EurAsia	AQT%sT
+Zone	Asia/Aqtau	3:21:04	-	LMT	1924 May  2 # or Aktau
 			4:00	-	SHET	1957 Mar # Fort Shevchenko Time
 			5:00 RussiaAsia SHE%sT	1991 Mar 31 2:00s
-			4:00	1:00	AKTST	1991 Sep 29 2:00s
-			4:00	-	AKTT	1992 Jan 19 2:00s # Aktau Time
-			5:00 RussiaAsia AKT%sT
+			4:00	1:00	AQTST	1991 Sep 29 2:00s
+			4:00	-	AQTT	1992 Jan 19 2:00s # Aqtau Time
+			5:00 E-EurAsia	AQT%sT	1995 Sep lastSun
+			4:00 E-EurAsia	AQT%sT
 
 # Kirgizstan
+# 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	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Bishkek	4:58:24 -	LMT	1924 May  2
 			5:00	-	FRUT	1957 Mar    # Frunze Time
 			6:00 RussiaAsia FRU%sT	1991 Mar 31 2:00s
 			5:00	1:00	FRUST	1991 Aug 31 # independence
-			5:00 RussiaAsia KG%sT		    # Kirgizstan Time
+			5:00	Kirgiz	KG%sT		    # Kirgizstan Time
 
 ###############################################################################
 
@@ -630,10 +672,13 @@ Rule	Lebanon	1973	1977	-	May	1	0:00	1:00	S
 Rule	Lebanon	1978	only	-	Apr	30	0:00	1:00	S
 Rule	Lebanon	1978	only	-	Sep	30	0:00	0	-
 Rule	Lebanon	1984	1987	-	May	1	0:00	1:00	S
-Rule	Lebanon	1984	max	-	Oct	16	0:00	0	-
+Rule	Lebanon	1984	1991	-	Oct	16	0:00	0	-
 Rule	Lebanon	1988	only	-	Jun	1	0:00	1:00	S
 Rule	Lebanon	1989	only	-	May	10	0:00	1:00	S
-Rule	Lebanon	1990	max	-	May	1	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	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Beirut	2:22:00 -	LMT	1880
 			2:00	Lebanon	EE%sT
@@ -673,8 +718,11 @@ Zone	Indian/Maldives	4:54:00 -	LMT	1880	# Male
 # 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	max	-	Mar	lastSun	2:00	1:00	S
-Rule	Mongol	1985	max	-	Sep	lastSun	3: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	1995	-	Sep	lastSun	0:00	0	-
+Rule	Mongol	1996	max	-	Oct	Fri>=22	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #Zone	Asia/Dariv	6:14:32 -	LMT	1905 Aug
 #			6:00	-	DART	1978	# Dariv Time
@@ -712,9 +760,9 @@ Zone	Asia/Karachi	4:28:12 -	LMT	1907
 Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
 Rule EgyptAsia	1957	1958	-	Oct	 1	0:00	0	-
 Rule EgyptAsia	1958	only	-	May	 1	0:00	1:00	S
-Rule EgyptAsia	1959	1981	-	May	 1	1: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	max	-	Oct	 1	3:00	0	-
+Rule EgyptAsia	1966	only	-	Oct	 1	3:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
 			2:00	-	EET	1957 May 10
@@ -806,8 +854,16 @@ Rule	Syria	1987	1988	-	Oct	31	2:00	0	-
 Rule	Syria	1988	only	-	Mar	15	2:00	1:00	S
 Rule	Syria	1989	only	-	Mar	31	2:00	1:00	S
 Rule	Syria	1989	only	-	Oct	1	2:00	0	-
-Rule	Syria	1990	max	-	Apr	1	2:00	1:00	S
-Rule	Syria	1990	max	-	Sep	30	2:00	0	-
+Rule	Syria	1990	only	-	Apr	1	2:00	1:00	S
+Rule	Syria	1990	only	-	Sep	30	2:00	0	-
+Rule	Syria	1991	only	-	Apr	 1	0:00	1:00	S
+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
+Rule	Syria	1994	max	-	Oct	 1	0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Damascus	2:25:12 -	LMT	1920
 			2:00	Syria	EE%sT
@@ -820,10 +876,6 @@ Zone	Asia/Dushanbe	4:35:12 -	LMT	1924 May  2
 			5:00	1:00	DUSST	1991 Sep  9 # independence
 			5:00 RussiaAsia	TJ%sT	1992
 			5:00	-	TJT		    # Tajikistan Time
-# Shanks has Dushanbe at 5:00 (6:00 summer) after 1991,
-# but a cable from the American Embassy at Dushanbe
-# <URL:http://www.itaiep.doc.gov/bisnis/cables/960703ti.html> (1996-07-02)
-# says that Tajikistan is at 5:00.  Guess no DST after 1991.
 
 # Thailand
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -836,12 +888,10 @@ Zone	Asia/Bangkok	6:42:04	-	LMT	1880
 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 Oct 27 # independence
-			4:00 RussiaAsia	TM%sT	1992	    # Turkmenistan Time
-			4:00	-	TMT
-# Shanks has Ashkhabad at 4:00 (5:00 summer) after 1991, but
-# DHL <URL:http://www.dhl.com/dhlinfo/country/turkmeni.html> (1996-07-26)
-# reports 4:00.  Guess no DST after 1991.
+			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
 
 # United Arab Emirates
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
diff --git a/time/australasia b/time/australasia
index 27e018bcde..be15771b07 100644
--- a/time/australasia
+++ b/time/australasia
@@ -1,4 +1,4 @@
-# @(#)australasia	7.29
+# @(#)australasia	7.30
 # This file also includes Pacific islands.
 
 # Notes are at the end of this file
@@ -35,17 +35,33 @@ Zone Australia/Perth	 7:43:24 -	LMT	1895 Dec
 			 8:00	1:00	WST	1992 Mar Sun>=1 2:00s
 			 8:00	-	WST
 # Queensland
+#
+# From Alex Livingston <alex@agsm.unsw.edu.au> (1996-11-01):
+# I have heard or read more than once that some resort islands off the coast
+# of Queensland chose to keep observing daylight-saving time even after
+# Queensland ceased to.
+#
+# From Paul Eggert (1996-11-22):
+# IATA SSIM (1993-02/1994-09) say that the Holiday Islands (Hayman, Lindeman,
+# Hamilton) observed DST for two years after the rest of Queensland stopped.
+# Hamilton is the largest, but there is also a Hamilton in Victoria,
+# so use Lindeman.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	QL	1989	1991	-	Oct	lastSun	2:00s	1:00	-
+Rule	QL	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	-
 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	-	EST	1989 Oct lastSun 2:00s
-			10:00	1:00	EST	1990 Mar Sun>=1 2:00s
-			10:00	-	EST	1990 Oct lastSun 2:00s
-			10:00	1:00	EST	1991 Mar Sun>=1 2:00s
-			10:00	-	EST	1991 Oct lastSun 2:00s
-			10:00	1:00	EST	1992 Mar Sun>=1 2:00s
-			10:00	-	EST
+			10:00	QL	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	Holiday	EST
 
 # South Australia
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
@@ -289,11 +305,13 @@ Rule	NZ	1990	max	-	Oct	Sun>=1	2:00s	1:00	D
 Rule	NZ	1975	only	-	Feb	23	2:00s	0	S
 Rule	NZ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
 Rule	NZ	1990	max	-	Mar	Sun>=15	2:00s	0	S
+Rule	Chatham	1990	max	-	Oct	Sun>=1	2:45s	1:00	D
+Rule	Chatham	1991	max	-	Mar	Sun>=15	2:45s	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Pacific/Auckland	11:39:04 -	LMT	1868
 			11:30	NZ	NZ%sT	1940 Sep 29 2:00
 			12:00	NZ	NZ%sT
-Zone Pacific/Chatham	12:45	NZ	CHA%sT
+Zone Pacific/Chatham	12:45	Chatham	CHA%sT
 
 
 # Antipodes Is, Kermadec Is
@@ -375,9 +393,9 @@ Zone Pacific/Funafuti	11:56:52 -	LMT	1901
 Rule	Vanuatu	1983	only	-	Sep	25	0:00	1:00	S
 Rule	Vanuatu	1984	1991	-	Mar	Sun>=23	0:00	0	-
 Rule	Vanuatu	1984	only	-	Oct	23	0:00	1:00	S
-Rule	Vanuatu	1985	1990	-	Sep	Sun>=23	0:00	1:00	S
-Rule	Vanuatu	1991	max	-	Sep	lastSun	0:00	1:00	S
-Rule	Vanuatu	1992	max	-	Mar	lastSun	0:00	0	-
+Rule	Vanuatu	1985	1991	-	Sep	Sun>=23	0:00	1:00	S
+Rule	Vanuatu	1992	1993	-	Jan	Sun>=23	0:00	0	-
+Rule	Vanuatu	1992	only	-	Oct	Sun>=23	0:00	1:00	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Pacific/Efate	11:13:16 -	LMT	1912 Jan 13		# Vila
 			11:00	Vanuatu	VU%sT	# Vanuatu Time
@@ -400,11 +418,19 @@ 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-01-22);
+# From Paul Eggert <eggert@twinsun.com> (1996-11-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 noted, it is the source for the data above.
+#
+# Gwillim Law <LAW@encmail.encompass.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.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
@@ -799,8 +825,11 @@ 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.
 #
-# Shanks gives no data for Chatham, but usno1995 says it's +12:45/+13:45.
-# Guess NZ switchover rules for now.
+# 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)
+# gives the NZ rules but with transitions at 2:45 local standard time.
+# Guess that they adopted DST in 1990.
 
 ###############################################################################
 
diff --git a/time/etcetera b/time/etcetera
index 73ad68ee0a..c47fae7a68 100644
--- a/time/etcetera
+++ b/time/etcetera
@@ -1,15 +1,19 @@
-# @(#)etcetera	7.5
+# @(#)etcetera	7.6
 
-# All of these are set up just so people can "zic -l" to a timezone
-# that's right for their area, even if it doesn't have a name or DST rules
-# (half hour zones are too much to bother with -- when someone asks!)
+# These entries are mostly present for historical reasons, so that
+# people in areas not otherwise covered by the tz files could "zic -l"
+# to a time zone that was right for their area.  These days, the
+# tz files cover almost all the inhabited world, so there's little
+# need now for the entries that are not on UTC.
 
 Zone	Etc/GMT		0	-	GMT
-Link	Etc/GMT				Etc/UTC
-Link	Etc/GMT				Etc/UCT
-Link	Etc/GMT				Etc/Universal
+Zone	Etc/UTC		0	-	UTC
+Zone	Etc/UCT		0	-	UCT
+
+Link	Etc/UTC				Etc/Universal
+Link	Etc/UTC				Etc/Zulu
+
 Link	Etc/GMT				Etc/Greenwich
-Link	Etc/GMT				Etc/Zulu
 Link	Etc/GMT				Etc/GMT-0
 Link	Etc/GMT				Etc/GMT+0
 Link	Etc/GMT				Etc/GMT0
diff --git a/time/europe b/time/europe
index abeba98386..6eb92b769d 100644
--- a/time/europe
+++ b/time/europe
@@ -1,14 +1,22 @@
-# @(#)europe	7.40
+# @(#)europe	7.41
 
 # 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-09-03):
+# From Paul Eggert <eggert@twinsun.com> (1996-11-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.
+#
+# Gwillim Law <LAW@encmail.encompass.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.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
@@ -27,6 +35,7 @@
 #	 0:00	WET WEST Western Europe
 #	 1:00	CET CEST Central Europe
 #	 2:00	EET EEST Eastern Europe
+#	 3:00	MSK MSD	Moscow
 #
 # See the `africa' file for time zone naming and abbreviation conventions.
 #
@@ -826,6 +835,14 @@ Rule	C-Eur	1979	1995	-	Sep	lastSun	 2:00s	0	-
 Rule	C-Eur	1981	max	-	Mar	lastSun	 2:00s	1:00	S
 Rule	C-Eur	1996	max	-	Oct	lastSun	 2:00s	0	-
 
+# E-Eur differs from EU only in that E-Eur switches at midnight local time.
+Rule	E-Eur	1977	1980	-	Apr	Sun>=1	 0:00	1:00	S
+Rule	E-Eur	1977	only	-	Sep	lastSun	 0:00	0	-
+Rule	E-Eur	1978	only	-	Oct	 1	 0:00	0	-
+Rule	E-Eur	1979	1995	-	Sep	lastSun	 0:00	0	-
+Rule	E-Eur	1981	max	-	Mar	lastSun	 0:00	1:00	S
+Rule	E-Eur	1996	max	-	Oct	lastSun	 0:00	0	-
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 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
@@ -836,15 +853,20 @@ 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 Andrew A. Chernov <ache@astral.msk.su> (1993-11-12):
+# 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	-	Sep	 1	 0:00	1:00	S
 Rule	Russia	1921	only	-	Oct	 1	 0:00	0	-
 Rule	Russia	1981	1984	-	Apr	 1	 0:00	1:00	S
 Rule	Russia	1981	1983	-	Oct	 1	 0:00	0	-
-Rule	Russia	1984	max	-	Sep	lastSun	 2:00s	0	-
-Rule	Russia	1985	max	-	Mar	lastSun	 2:00s	1:00	S
+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
+Rule	Russia	1993	1995	-	Sep	lastSun	 2:00s	0	-
+Rule	Russia	1996	max	-	Oct	lastSun	 2:00s	0	-
 
 # These are for backward compatibility with older versions.
 
@@ -913,7 +935,8 @@ Rule	Albania	1984	only	-	Oct	 1	0:00	0	-
 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
+			1:00	W-Eur	CE%sT	1991
+			1:00	EU	CE%sT
 
 # Andorra
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -944,11 +967,13 @@ Zone	Europe/Vienna	1:05:20 -	LMT	1893 Apr
 # 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	MOS%sT	1922 Oct # Moscow Time
+			3:00	Russia	MSK/MSD	1922 Oct
 			2:00	-	EET	1930 Jun 21
-			3:00	Russia	MOS%sT	1991 Mar 31 2:00s
+			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
+			2:00	-	EET	1992 Mar 29 0:00
+			2:00	1:00	EEST	1992 Sep 27 0:00
+			2:00	Russia	EE%sT
 
 # Belgium
 # Whitman and Shanks disagree; go with Shanks, usually.
@@ -1021,7 +1046,8 @@ Zone	Europe/Sofia	1:33:16 -	LMT	1880
 			1:00	C-Eur	CE%sT	1945 Apr  2  3:00
 			2:00	-	EET	1979 Mar 31 23:00
 			2:00	Bulg	EE%sT	1982 Sep 26  2:00
-			2:00	C-Eur	EE%sT
+			2:00	C-Eur	EE%sT	1991
+			2:00	E-Eur	EE%sT
 
 # Croatia
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1077,30 +1103,54 @@ Zone Europe/Copenhagen	 0:50:20 -	LMT	1890
 Zone Atlantic/Faeroe	-0:27:04 -	LMT	1908 Jan 11	# Torshavn
 			 0:00	-	WET	1981
 			 0:00	EU	WE%sT
-Zone America/Scoresbysund -1:29:00 -	LMT	1916 Jul 28
+#
+# From Paul Eggert (1996-11-22):
+# Greenland joined the EU as part of Denmark, obtained home rule on 1979-05-01,
+# and left the EU on 1985-02-01.  It therefore should have been using EU
+# rules at least through 1984.  Shanks says Scoresbysund and Godthab
+# used C-Eur rules after 1980, but IATA SSIM (1991/1996) says they use EU
+# rules since at least 1991.  Assume EU rules since 1980.
+
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+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
 			-2:00	-	CGT	1980 Apr  6 2:00
 			-2:00	C-Eur	CG%sT	1981 Mar 29
-			-1:00	C-Eur	EG%sT
-Zone America/Godthab	-3:26:56 -	LMT	1916 Jul 28
+			-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	C-Eur	WG%sT
-Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28
-			-4:00	-	AST
+			-3:00	EU	WG%sT
+Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28 # Pituffik
+			-4:00	Thule	A%sT
 
 # Estonia
 # From Peter Ilieve <peter@memex.co.uk> (1994-10-15):
 # A relative in Tallinn confirms the accuracy of the data for 1989 onwards
 # [through 1994] and gives the legal authority for it,
 # a regulation of the Government of Estonia, No. 111 of 1989....
+#
+# From Peter Ilieve <peter@aldie.co.uk> (1996-10-28):
+# [IATA SSIM (1992/1996) claims that the Baltic republics switch at 01:00s,
+# but a relative confirms that Estonia still switches at 02:00s, writing:]
+# ``I do not [know] exactly but there are some little different
+# (confusing) rules for International Air and Railway Transport Schedules
+# conversion in Sunday connected with end of summer time in Estonia....
+# 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.''
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Europe/Tallinn	1:39:00	-	LMT	1880
 			1:39:00	-	TMT	1918 Feb # Tallinn Mean Time
 			1:00	C-Eur	CE%sT	1919 Jul
 			1:39:00	-	TMT	1921 May
 			2:00	-	EET	1940 Aug  6
-			3:00	-	MOST	1941 Sep 15 # Moscow Time
+			3:00	-	MSK	1941 Sep 15
 			1:00	C-Eur	CE%sT	1944 Sep 22
-			3:00	Russia	MOS%sT	1989 Mar 26 2:00s
+			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
 
@@ -1418,6 +1468,14 @@ 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.
+# 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	-
 # 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
@@ -1426,11 +1484,11 @@ Zone	Europe/Riga	1:36:24	-	LMT	1880
 			1:36:24	1:00	LST	1919 May 22 3:00
 			1:36:24	-	RMT	1926 May 11
 			2:00	-	EET	1940 Aug  5
-			3:00	-	MOST	1941 Jul # Moscow Time
+			3:00	-	MSK	1941 Jul
 			1:00	C-Eur	CE%sT	1944 Aug  8
-			3:00	Russia	MOS%sT	1991 Mar 31 2:00s
+			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
+			2:00	Latvia	EE%sT
 
 # Liechtenstein
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1446,11 +1504,14 @@ Zone	Europe/Vilnius	1:41:16	-	LMT	1880
 			1:00	-	CET	1920 Jul 12
 			2:00	-	EET	1920 Oct  9
 			1:00	-	CET	1940 Aug  3
-			3:00	-	MOST	1941 Jun 24 # Moscow Time
+			3:00	-	MSK	1941 Jun 24
 			1:00	C-Eur	CE%sT	1944 Aug
-			3:00	Russia	MOS%sT	1991 Mar 31 2:00s
+			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.
 
 # Luxembourg
 # Whitman disagrees with most of these dates in minor ways; go with Shanks.
@@ -1517,9 +1578,9 @@ Zone	Europe/Malta	0:58:04 -	LMT	1893 Nov  2	# Valletta
 # 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	MOS%sT	1991 Mar 31 2:00s # Moscow Time
+			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
+			2:00	E-Eur	EE%sT
 
 # Monaco
 # Shanks gives 0:09 for Paris Mean Time; go with Howse's more precise 0:09:21.
@@ -1631,9 +1692,30 @@ Zone	Europe/Warsaw	1:24:00 -	LMT	1880
 			1:00	C-Eur	CE%sT	1944 Oct
 			1:00	Poland	CE%sT	1977 Apr  3 1:00
 			1:00	W-Eur	CE%sT
+# 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.
+# Stick with W-Eur for now.
 
 # 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
+# (from WET to MET or CET) to harmonize with EEC.
+#
+# Martin Bruckmann <martin@ua.pt> (1996-02-29) reports via Peter Ilieve
+# that Portugal is reverting to 0:00 by not moving its clocks this spring.
+# The new Prime Minister was fed up with getting up in the dark in the winter.
+#
+# From Paul Eggert (1996-11-12):
+# IATA SSIM (1991-09) reports several 1991-09 and 1992-09 transitions
+# at 02:00u, not 01:00u.  Assume that these are typos.
+# IATA SSIM (1991/1992) reports that the Azores were at -1:00.
+# IATA SSIM (1993-02) says +0:00; later issues (through 1996-09) say -1:00.
+# Guess that the Azores changed to EU rules in 1992 (since that's when Portugal
+# harmonized with the EU), and that they stayed +0:00 that winter.
+#
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Port	1916	only	-	Jun	17	23:00	1:00	S
 # Whitman gives 1916 Oct 31; go with Shanks.
@@ -1701,23 +1783,16 @@ Zone	Europe/Lisbon	-0:36:32 -	LMT	1884
 			 0:00	Port	WE%sT	1966 Apr  3 2:00
 			 1:00	-	CET	1976 Sep 26 1:00
 			 0:00	Port	WE%sT	1983 Sep 25 1:00s
-# From Rui Pedro Salgueiro <rps@inescca.inescc.pt> (1992-11-12):
-# Portugal has recently (September, 27) changed timezone
-# (from WET to MET or CET) to harmonize with EEC.
-			 0:00	EU	WE%sT	1992 Sep 27 1:00s
-# Martin Bruckmann <martin@ua.pt> (1996-02-29) reports via Peter Ilieve
-# that Portugal is reverting to 0:00 by not moving its clocks this spring.
-# The new Prime Minister was fed up with getting up in the dark in the winter.
+			 0:00	W-Eur	WE%sT	1992 Sep 27 1:00s
 			 1:00	EU	CE%sT	1996 Mar 31 1:00u
 			 0:00	EU	WE%sT
-# We don't know what happened to Madeira or the Azores,
-# so we'll just use Shanks for now.
-# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Atlantic/Azores	-1:42:40 -	LMT	1884		# Ponta Delgada
 			-1:55	-	HMT	1911 May 24  # Horta Mean Time
 			-2:00	Port	AZO%sT	1966 Apr  3 2:00 # Azores Time
 			-1:00	Port	AZO%sT	1983 Sep 25 1:00s
-			-1:00	W-Eur	AZO%sT
+			-1:00	W-Eur	AZO%sT	1992 Sep 27 1:00s
+			 0:00	EU	WE%sT	1993 Mar 28 1:00u
+			-1:00	EU	AZO%sT
 Zone Atlantic/Madeira	-1:07:36 -	LMT	1884		# Funchal
 			-1:08	-	FMT	1911 May 24  # Funchal Mean Time
 			-1:00	Port	MAD%sT	1966 Apr  3 2:00 # Madeira Time
@@ -1733,38 +1808,62 @@ Rule	Romania	1979	only	-	May	27	 0:00	1:00	S
 Rule	Romania	1979	only	-	Sep	lastSun	 0:00	0	-
 Rule	Romania	1980	only	-	Apr	 5	23:00	1:00	S
 Rule	Romania	1980	only	-	Sep	lastSun	 1:00	0	-
+Rule	Romania	1991	1993	-	Mar	lastSun	 0:00s	1:00	S
+Rule	Romania	1991	1993	-	Sep	lastSun	 0:00s	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Europe/Bucharest	1:44:24 -	LMT	1891 Oct
 			1:44:24	-	BMT	1931 Jul 24	# Bucharest MT
 			2:00	Romania	EE%sT	1981 Mar 29 2:00s
-			2:00	C-Eur	EE%sT
+			2:00	C-Eur	EE%sT	1991
+			2:00	Romania	EE%sT	1994
+			2:00	E-Eur	EE%sT
 
 # Russia
 # From Shanks (1991):
 # In 1929 the Soviet Union instituted a 5 day week; in 1932 it instituted
 # a 6 day week; on 1940-06-27 it returned to the Gregorian week.
 #
-# From Paul Eggert <eggert@twinsun.com> (1996-09-03):
-# Moscow rules after 1991 are from Andrew A. Chernov <ache@astral.msk.su>.
-# I invented the time zone names, and (unless otherwise specified)
-# guessed what happened after 1991; the clocks were chaotic, and we know little.
-# The rest is from Shanks.
+# 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.
+# 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.
+#
+# From Andrey A. Chernov <ache@nagual.ru> (1996-10-04):
+# `MSK' and `MSD' were born and used initially on Moscow computers with
+# Unix-like OSes by several developer groups (e.g. Demos group, Kiae group)....
+# The next step was the UUCP network, the Relcom predecessor
+# (used mainly for mail), and MSK/MSD was actively used there.
+#
+# From Chris Carrier <72157.3334@CompuServe.COM> (1996-10-30):
+# According to a friend of mine who rode the Trans-Siberian Railroad from
+# Moscow to Irkutsk in 1995, public air and rail transport in Russia ...
+# still follows Moscow time, no matter where in Russia it is located.
 #
 # 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
+			 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
-			 3:00	Russia	MOS%sT	1922 Oct # Moscow TIme
+			 3:00	Russia	MSK/MSD	1922 Oct
 			 2:00	-	EET	1930 Jun 21
-			 3:00	Russia	MOS%sT	1991 Mar 31 2:00s
+			 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	MOS%sT
-Zone Europe/Kuybyshev	 3:20:36 -	LMT	1924 May  2
+			 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	-	KUYT	1992 Jan 19 2:00s
-			 4:00	Russia	KUY%sT
+			 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
 			 5:00	Russia	SVE%sT	1991 Mar 31 2:00s
@@ -1916,6 +2015,8 @@ Zone	Atlantic/Canary	-1:01:36 -	LMT	1922 Mar # Las Palmas de Gran C.
 			 0:00	-	WET	1980 Apr  6 0:00s
 			 0:00	1:00	WEST	1980 Sep 28 0:00s
 			 0:00	EU	WE%sT
+# IATA SSIM (1996-09) says the Canaries switch at 2:00u, not 1:00u.
+# Ignore this for now, as the Canaries are part of the EU.
 
 # Sweden
 
@@ -2026,7 +2127,8 @@ Zone	Europe/Istanbul	1:55:52 -	LMT	1880
 			2:00	Turkey	EE%sT	1978 Oct 15
 			3:00	Turkey	TR%sT	1985 Apr 20 # Turkey Time
 			2:00	Turkey	EE%sT	1986
-			2:00	C-Eur	EE%sT
+			2:00	C-Eur	EE%sT	1991
+			2:00	EU	EE%sT
 Link	Europe/Istanbul	Asia/Istanbul	# Istanbul is in both continents.
 
 # Ukraine
@@ -2053,23 +2155,28 @@ 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]
 Zone Europe/Kiev	2:02:04 -	LMT	1880
 			2:02:04	Ukraine	%s	1924 May  2
 			2:00	-	EET	1930 Jun 21
-			3:00	Russia	MOS%sT	1990 Jul 17 # Moscow Time
-			2:00	C-Eur	EE%sT
+			3:00	Russia	MSK/MSD	1990 Jul 17
+			2:00	E-Eur	EE%sT	1996
+			2:00	EU	EE%sT
 Zone Europe/Simferopol	2:16:24 -	LMT	1880
 			2:08:00	Crimea	%s	1924 May  2
 			2:00	-	EET	1930 Jun 21
-			3:00	Russia	MOS%sT	1991 Mar 31 2:00s
+			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> (1994-05-28):
-# Today's _Economist_ (p 45) reports that Crimea switched
-# from Kiev to Moscow time sometime after the January elections.
-# For now, we'll guess that there was a 2-hour leap forward on March 27.
-			2:00	C-Eur	EE%sT	1994 Mar 27 2:00s
-			3:00	Russia	MOS%sT
+# From Paul Eggert <eggert@twinsun.com> (1996-10-21):
+# The _Economist_ (1994-05-28, p 45) reports that most of 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
 
 # Yugoslavia
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
diff --git a/time/northamerica b/time/northamerica
index 5c0c02cc93..af81c5edb9 100644
--- a/time/northamerica
+++ b/time/northamerica
@@ -1,4 +1,4 @@
-# @(#)northamerica	7.28
+# @(#)northamerica	7.29
 # also includes Central America and the Caribbean
 
 # This data is by no means authoritative; if you think you know better,
@@ -462,11 +462,19 @@ Link	Pacific/Honolulu	HST
 ################################################################################
 
 
-# From Paul Eggert <eggert@twinsun.com> (1993-11-18):
+# From Paul Eggert <eggert@twinsun.com> (1996-11-22):
 # 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).
-# Except where otherwise noted, it is the source for the data below.
+#
+# Gwillim Law <LAW@encmail.encompass.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.
 #
 # Another source occasionally used is Edward W. Whitman, World Time Differences,
 # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
@@ -523,7 +531,7 @@ Rule	Canada	1974	max	-	Oct	lastSun	2:00	0	S
 Rule	Canada	1987	max	-	Apr	Sun>=1	2:00	1:00	D
 
 
-# Newfoundland
+# Newfoundland (except Labrador)
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	StJohns	1917	1918	-	Apr	Sun>=8	2:00	1:00	D
@@ -560,11 +568,23 @@ Rule	StJohns	1989	max	-	Apr	Sun>=1	2:00	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
-			-3:31	StJohns	N%sT	1935 Mar 30
+			-3:30:52 StJohns N%sT	1935 Mar 30
 			-3:30	StJohns	N%sT
 
 
-# Labrador, New Brunswick, Nova Scotia, Prince Edward I
+# east Labrador
+
+# The name `Happy Valley-Goose Bay' is too long; use `Goose Bay'.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Goose_Bay	-4:01:40 -	LMT	1884 # Happy Valley-Goose Bay
+			-3:30:52 StJohns NST	1919
+			-3:30:52 -	NST	1935 Mar 30
+			-3:30	-	NST	1936
+			-3:30	StJohns	N%sT	1966 Mar 15 2:00
+			-4:00	StJohns	A%sT
+
+
+# west Labrador, New Brunswick, Nova Scotia, Prince Edward I
 
 # From Paul Eggert (1996-06-12):
 # Shanks writes that since 1970 most of this region has been like Halifax.
@@ -825,9 +845,17 @@ Zone America/Dawson_Creek -8:00:56 -	LMT	1884
 
 # Northwest Territories, Yukon
 
-# From Paul Eggert (1996-06-12):
+# From Paul Eggert (1996-10-07):
 # 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;
+#	see Interpretation Act, R.S.C. 1985, c. I-21, s. 35(1).
+#	* C.O. 1973/214 switched Yukon to PST on 1973-10-28 00:00.
+#	* O.I.C. 1980/02 established DST.
+#	* 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.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	NT_YK	1918	only	-	Apr	14	2:00	1:00	D
@@ -857,7 +885,7 @@ Zone America/Whitehorse	-9:00:12 -	LMT	1900 Aug 20
 			-9:00	NT_YK	Y%sT	1966 Jul 1 2:00
 			-8:00	NT_YK	P%sT
 Zone America/Dawson	-9:17:40 -	LMT	1900 Aug 20
-			-9:00	NT_YK	Y%sT	1973 Oct lastSun 2:00
+			-9:00	NT_YK	Y%sT	1973 Oct 28 0:00
 			-8:00	NT_YK	P%sT
 
 
@@ -1070,8 +1098,10 @@ Zone	America/Cayman	-5:25:32 -	LMT	1890		# Georgetown
 # 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
-Rule	CR	1991	only	-	Jan	19	0:00	1:00	D
-Rule	CR	1991	only	-	Jul	1	0:00	0	S
+Rule	CR	1991	1992	-	Jan	Sat>=15	0:00	1:00	D
+# IATA SSIM (1991-09) says the following was at 1:00; go with Shanks.
+Rule	CR	1991	only	-	Jul	 1	0:00	0	S
+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
@@ -1114,10 +1144,11 @@ Rule	Cuba	1978	only	-	May	7	0:00	1:00	D
 Rule	Cuba	1978	1980	-	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	max	-	Oct	Sun>=8	0:00	0	S
+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	only	-	Apr	1	0:00	1:00	D
-Rule	Cuba	1991	max	-	Mar	Sun>=14	0:00	1:00	D
+Rule	Cuba	1990	max	-	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
 
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Havana	-5:29:28 -	LMT	1890
@@ -1168,6 +1199,8 @@ Rule	Guat	1973	only	-	Nov	25	0:00	1:00	D
 Rule	Guat	1974	only	-	Feb	24	0:00	0	S
 Rule	Guat	1983	only	-	May	21	0:00	1:00	D
 Rule	Guat	1983	only	-	Sep	22	0:00	0	S
+Rule	Guat	1991	only	-	Mar	23	0:00	1:00	D
+Rule	Guat	1991	only	-	Sep	 7	0:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Guatemala	-6:02:04 -	LMT	1918 Oct 5
 			-6:00	Guat	C%sT
@@ -1177,8 +1210,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
-Rule	Haiti	1988	max	-	Apr	Sun>=1	2:00	1:00	D
-Rule	Haiti	1988	max	-	Oct	lastSun	2: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
 # 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
@@ -1203,7 +1237,8 @@ Zone America/Tegucigalpa -5:48:52 -	LMT	1921 Apr
 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:00	US	E%sT
+			-5:00	US	E%sT	1984
+			-5:00	-	EST
 
 # Martinique
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1222,12 +1257,15 @@ Zone America/Montserrat	-4:08:52 -	LMT	1911 Jul 1 0:01   # Plymouth
 # 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
+Rule	Nic	1992	only	-	Jan	1	4:00	1:00	D
+Rule	Nic	1992	only	-	Sep	24	0:00	0	S
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Managua	-5:45:08 -	LMT	1890
 			-5:45	-	MMT	1934 Jun 23  # Managua Mean Time
 			-6:00	-	CST	1973 May
 			-5:00	-	EST	1975 Feb 16
-			-6:00	Nic	C%sT
+			-6:00	Nic	C%sT	1993 Jan 1 4:00
+			-5:00	-	EST
 
 # Panama
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -1268,11 +1306,17 @@ Zone America/St_Vincent	-4:04:56 -	LMT	1890		# Kingstown
 			-4:00	-	AST
 
 # Turks and Caicos
+# From Paul Eggert (1996-11-22):
+# Shanks says they use US DST rules, but IATA SSIM (1991/1996)
+# 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
+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:00	-	EST	1979 Apr 29 2:00
-			-5:00	US	E%sT
+			-5:00	TC	E%sT
 
 # British Virgin Is
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
diff --git a/time/southamerica b/time/southamerica
index cd8c84ec6f..1fdde5ebe5 100644
--- a/time/southamerica
+++ b/time/southamerica
@@ -1,14 +1,22 @@
-# @(#)southamerica	7.14
+# @(#)southamerica	7.15
 
 # 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-09-03):
+# From Paul Eggert <eggert@twinsun.com> (1996-11-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.
+#
+# Gwillim Law <LAW@encmail.encompass.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.
 #
 # The following abbreviations are used in this file.
 # Corrections are welcome!
@@ -103,11 +111,64 @@ Rule	Arg	1989	1992	-	Oct	Sun>=15	0:00	1:00	S
 # to the time zones (for daylight saving) are now made.
 #
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+#
+# Buenos Aires (BA), Distrito Federal (DF), Santa Cruz (SC),
+# Tierra del Fuego (TF) & Antartida e Islas
 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
+#
+# 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
+			-3:00	Arg	AR%sT	1991 Jul
+			-3:00	-	ART
+#
+# Cordoba (CB), Santiago del Estero (SE), Salta (SA), Tucuman (TM), La Rioja (LR), San Juan (SJ), San Luis (SL),
+# Neuquen (NQ), Rio Negro (RN)
+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
+			-3:00	Arg	AR%sT	1990 Jul
+			-3:00	-	ART
+#
+# Jujuy (JY)
+Zone America/Jujuy	-4:21:12 -	LMT	1894 Nov
+			-4:16:44 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct  6
+			-4:00	1:00	WARST	1992 Mar 15
+			-4:00	-	WART	1992 Oct 18
+			-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
+			-3:00	Arg	AR%sT	1990 Jul
+			-3:00	-	ART	1991 Jul
+			-3:00	Arg	AR%sT	1992 Jul
+			-3:00	-	ART
+#
+# Mendoza (MZ)
+Zone America/Mendoza	-4:35:16 -	LMT	1894 Nov
+			-4:16:44 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct 15
+			-4:00	1:00	WARST	1992 Mar  1
+			-4:00	-	WART	1992 Oct 18
+			-3:00	-	ART
 
 # Aruba
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
@@ -132,38 +193,55 @@ Zone	America/La_Paz	-4:32:36 -	LMT	1890
 # "[America/Porto_Acre]" is for the Territory of Acre;
 # "[America/Noronha]" is for Fernando De Noronha.
 
-# From Bob Devine (1988-01-28):
-# The only information I found is that there was no DST up to 1985.
-# But there was some before 1952!
-
-# From U. S. Naval Observatory (1989-01-16):
-# BRAZIL     WEST     5 H  BEHIND UTC    TERRITORY OF ACRE
-# BRAZIL     WEST     4 H  BEHIND UTC    ACRE OCT 23, '88-FEB 11,
-# BRAZIL                                 '89 (ESTIMATED)
-# BRAZIL     CENTRAL  4 H  BEHIND UTC    MANAUS
-# BRAZIL     CENTRAL  3 H  BEHIND UTC    MANAUS OCT 23, '88-FEB 11,
-# BRAZIL     CENTRAL                     '89 (ESTIMATED)
-# BRAZIL     EAST     3 H  BEHIND UTC    COASTAL STATES, RIO, SAO
-# BRAZIL     EAST                        PAULO, BRASILIA
-# BRAZIL     EAST     2 H  BEHIND UTC    COASTAL STATES, RIO, SAO
-# BRAZIL                                 PAULO, BRASILIA OCT 23,
-# BRAZIL                                 '88-FEB 11, '89
-# BRAZIL                                 (ESTIMATED)
-# BRAZIL              2 H  BEHIND UTC    ATLANTIC ISLANDS, FERNANDO
-# BRAZIL                                 DE NORONHA
-# BRAZIL              1 H  BEHIND UTC    OCT 23, '88-FEB 11, '89
-# BRAZIL                                 (ESTIMATED)
-# BRAZIL              3 H  BEHIND UTC    FOR MOST MAJOR AIRPORTS.
-
 # 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.
 # The rule change lasted only part of the day;
 # the federal government refused to follow the city's rules, and business
 # was in a chaos, so the mayor backed down that afternoon.
-# Shanks claims Acre stopped observing DST after 1988 Feb 7, but it
-# could just be that his table ran out of room.  We're extrapolating
-# about time zone changes after 1990 Feb 11.
+
+# From IATA SSIM (1996-02):
+# _Only_ the following states in BR1 observe DST: Rio Grande do Sul (RS),
+# Santa Catarina (SC), Parana (PR), Sao Paulo (SP), Rio de Janeiro (RJ),
+# Espirito Santo (ES), Minas Gerais (MG), Bahia (BA), Goias (GO),
+# Distrito Federal (DF), Tocantins (TO), Sergipe [SE] and Alagoas [AL].
+# [The last three states are new to this issue of the IATA SSIM.]
+
+# From Gwillim Law (1996-10-07):
+# Geography, history (Tocantins was part of Goias until 1989), and other
+# sources of time zone information lead me to believe that AL, SE, and TO were
+# always in BR1, and so the only change was whether or not they observed DST....
+# The earliest issue of the SSIM I have is 2/91.  Each issue from then until
+# 9/95 says that DST is observed only in the ten states I quoted from 9/95,
+# along with Mato Grosso (MT) and Mato Grosso do Sul (MS), which are in BR2
+# (UTC-4)....  The other two time zones given for Brazil are BR3, which is
+# UTC-5, no DST, and applies only in the state of Acre (AC); and BR4, which is
+# UTC-2, and applies to Fernando de Noronha (formerly FN, but I believe it's
+# become part of the state of Pernambuco).  The boundary between BR1 and BR2
+# has never been clearly stated.  They've simply been called East and West.
+# However, some conclusions can be drawn from another IATA manual: the Airline
+# Coding Directory, which lists close to 400 airports in Brazil.  For each
+# airport it gives a time zone which is coded to the SSIM.  From that
+# information, I'm led to conclude that the states of Amapa (AP), Ceara (CE),
+# 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:
+#
+# * 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.
+#
+# Under these assumptions Brazil needs 7 entries to cover all the distinct
+# time zone histories since 1970:
+#
+# 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.
 
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Brazil	1931	only	-	Oct	 3	11:00	1:00	D
@@ -185,21 +263,59 @@ 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	max	-	Oct	Sun>=15	 0:00	1:00	D
-Rule	Brazil	1990	max	-	Feb	Sun>=8	 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
 Zone America/Noronha	-2:09:40 -	LMT	1914
 			-2:00	-	FST	1963 Dec 9
-			-2:00	Brazil	F%sT
+			-2:00	Brazil	F%sT	1990 Jul
+			-2:00	-	FST
+#
+# Amapa, east Para, Maranhao, Piaui, Ceara, Rio Grande do Norte, Paraiba,
+# Pernambuco (except Fernando de Noronha)
+Zone America/Fortaleza	-2:34:00 -	LMT	1914
+			-3:00	-	EST	1963 Dec 9
+			-3:00	Brazil	E%sT	1990 Jul
+			-3:00	-	EST
+#
+# Alagoas, Sergipe, Tocantins
+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
+#
+# Bahia, Goias, Distrito Federal, Minas Gerais, Espirito Santo, Rio de Janeiro,
+# Sao Paulo, Parana, Santa Catarina, Rio Grande do Sul
 Zone America/Sao_Paulo	-3:06:28 -	LMT	1914
 			-3:00	Brazil	E%sT
-Zone America/Manaus	-4:00:04 -	LMT	1914
+#
+# 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
+#
+# Roraima, west Para, Amazonas, Rondonia
+Zone America/Manaus	-4:00:04 -	LMT	1914
+			-4:00	-	WST	1963 Dec 9
+			-4:00	Brazil	W%sT	1990 Jul
+			-4:00	-	WST
+#
+# 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
+			-5:00	Brazil	A%sT	1988 Jul
+			-5:00	-	AST
 #
 # Martin Vaz and Trinidade are like America/Noronha.
 
@@ -217,6 +333,8 @@ 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	-
+# 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.
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Santiago	-4:42:40 -	LMT	1890
 			-4:42:40 -	SMT	1910	    # Santiago Mean Time
@@ -233,10 +351,13 @@ Zone Pacific/Easter	-7:17:28 -	LMT	1890	    # Mataveri
 
 
 # Colombia
+# 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	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Bogota	-4:56:20 -	LMT	1884 Mar 13
 			-4:56:20 -	BMT	1914 Nov 23 # Bogota Mean Time
-			-5:00	-	COT	# Colombia Time
+			-5:00	CO	CO%sT	# Colombia Time
 # Malpelo, Providencia, San Andres
 # no information; probably like America/Bogota
 
@@ -265,8 +386,9 @@ 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	max	-	Sep	Sun>=9	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
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Atlantic/Stanley	-3:51:24 -	LMT	1890
 			-3:51:24 -	SMT	1912 Mar 12  # Stanley Mean Time
@@ -285,8 +407,9 @@ Zone America/Cayenne	-3:29:20 -	LMT	1911 Jul
 Zone	America/Guyana	-3:52:40 -	LMT	1915 Mar	# Georgetown
 			-3:45	-	GBGT	1966 May 26 # Br Guiana Time
 			-3:45	-	GYT	1975 Jul 31 # Guyana Time
-			-3:00	-	GYT
-
+			-3:00	-	GYT	1991
+# IATA SSIM (1996-06) says -4:00.  Assume a 1991 switch.
+			-4:00	-	GYT
 
 # Paraguay
 
@@ -303,10 +426,17 @@ Zone	America/Guyana	-3:52:40 -	LMT	1915 Mar	# Georgetown
 Rule	Para	1975	1978	-	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	max	-	Apr	 1	0:00	0	-
+Rule	Para	1980	1991	-	Apr	 1	0:00	0	-
 Rule	Para	1980	1988	-	Oct	 1	0:00	1:00	S
 Rule	Para	1989	only	-	Oct	22	0:00	1:00	S
-Rule	Para	1990	max	-	Oct	 1	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	1994	1995	-	Feb	lastSun	0:00	0	-
+Rule	Para	1996	max	-	Mar	 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
@@ -324,6 +454,8 @@ 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	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	America/Lima	-5:08:12 -	LMT	1890
 			-5:09	-	LMT	1908 Jul 28 # Lima Mean Time
@@ -396,7 +528,10 @@ 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
-Rule	Uruguay	1990	only	-	Mar	 4	 0:00	0	-
+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	1993	only	-	Feb	28	 0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone America/Montevideo	-3:44:44 -	LMT	1898 Jun 28
 			-3:44:44 -	MMT	1920 May  1	# Montevideo MT
diff --git a/time/zone.tab b/time/zone.tab
index fef6a7244f..9d86110ca7 100644
--- a/time/zone.tab
+++ b/time/zone.tab
@@ -31,9 +31,15 @@ AN	+1211-06900	America/Curacao
 AO	-0848+01314	Africa/Luanda
 AQ	-7750+16636	Antarctica/McMurdo	McMurdo Station, Ross Island
 AQ	-9000+00000	Antarctica/South_Pole	Amundsen-Scott Station, South Pole
-AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
+AQ	-6448-06406	Antarctica/Palmer	Palmer Station, Anvers Island
 AQ	-6736+06253	Antarctica/Mawson	Mawson Station, Holme Bay
-AR	-3436-05827	America/Buenos_Aires
+AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
+AR	-3436-05827	America/Buenos_Aires	E Argentina (BA, DF, SC, TF)
+AR	-3257-06040	America/Rosario	NE Argentina (SF, ER, CN, MN, CC, FM, LP, CH)
+AR	-3124-06411	America/Cordoba	W Argentina (CB, SA, TM, LR, SJ, SL, NQ, RN)
+AR	-2411-06518	America/Jujuy	Jujuy (JY)
+AR	-2828-06547	America/Catamarca	Catamarca (CT)
+AR	-3253-06849	America/Mendoza	Mendoza (MZ)
 AS	-1416-17042	Pacific/Pago_Pago
 AT	+4813+01620	Europe/Vienna
 AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
@@ -41,7 +47,8 @@ AU	-4253+14719	Australia/Hobart	Tasmania
 AU	-3749+14458	Australia/Melbourne	Victoria
 AU	-3352+15113	Australia/Sydney	New South Wales - most locations
 AU	-3157+14127	Australia/Broken_Hill	New South Wales - Broken Hill
-AU	-2728+15302	Australia/Brisbane	Queensland
+AU	-2728+15302	Australia/Brisbane	Queensland - most locations
+AU	-2016+14900	Australia/Lindeman	Queensland - Holiday Islands
 AU	-3455+13835	Australia/Adelaide	South Australia
 AU	-1228+13050	Australia/Darwin	Northern Territory
 AU	-3157+11551	Australia/Perth	Western Australia
@@ -59,9 +66,12 @@ BJ	+0629+00237	Africa/Porto-Novo
 BM	+3217-06446	Atlantic/Bermuda
 BN	+0456+11455	Asia/Brunei
 BO	-1630-06809	America/La_Paz
-BR	-0351-03225	America/Noronha	Atlantic islands
-BR	-2332-04637	America/Sao_Paulo	east Brazil
-BR	-0308-06001	America/Manaus	west Brazil
+BR	-0351-03225	America/Noronha	Fernando de Noronha
+BR	-0343-03830	America/Fortaleza	NE Brazil (AP, east PA, MA, PI, CE, RN, PR, PE)
+BR	-0940-03543	America/Maceio	ENE Brazil (AL, SE, TO)
+BR	-2332-04637	America/Sao_Paulo	S & SE Brazil (BA, GO, DF, MG, ES, RJ, SP, PR, SC, RS)
+BR	-1535-05605	America/Cuiaba	SW Brazil (MT, MS)
+BR	-0308-06001	America/Manaus	NW Brazil (RR, west PA, AM, RO)
 BR	-0934-06731	America/Porto_Acre	Acre
 BS	+2505-07721	America/Nassau
 BT	+2728+08939	Asia/Thimbu
@@ -69,8 +79,9 @@ BW	-2545+02555	Africa/Gaborone
 BY	+5354+02734	Europe/Minsk
 BZ	+1730-08812	America/Belize
 CA	+4734-05243	America/St_Johns	Newfoundland Island
-CA	+4439-06336	America/Halifax	Atlantic Time - Nova Scotia (most locations), New Brunswick, Labrador & PEI
+CA	+4439-06336	America/Halifax	Atlantic Time - Nova Scotia (most places), NB, W Labrador, E Quebec & PEI
 CA	+4612-05957	America/Glace_Bay	Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
+CA	+5320-06025	America/Goose_Bay	Atlantic Time - E Labrador
 CA	+6608-06544	America/Pangnirtung	Atlantic Time - Northwest Territories
 CA	+4531-07334	America/Montreal	Eastern Time - Ontario & Quebec - most locations
 CA	+4901-08816	America/Nipigon	Eastern Time - Ontario & Quebec - places that did not observe DST 1967-1973
@@ -189,7 +200,8 @@ KR	+3733+12658	Asia/Seoul
 KW	+2920+04759	Asia/Kuwait
 KY	+1918-08123	America/Cayman
 KZ	+4315+07657	Asia/Alma-Ata	east Kazakhstan
-KZ	+5016+07302	Asia/Aktau	west Kazakhstan
+KZ	+5017+05710	Asia/Aqtobe	central Kazakhstan
+KZ	+4431+05016	Asia/Aqtau	west Kazakhstan
 LA	+1758+10236	Asia/Vientiane
 LB	+3353+03530	Asia/Beirut
 LC	+1401-06100	America/St_Lucia
@@ -262,15 +274,16 @@ PY	-2516-05740	America/Asuncion
 QA	+2517+05132	Asia/Qatar
 RE	-2052+05528	Indian/Reunion
 RO	+4426+02606	Europe/Bucharest
+RU	+5443+02030	Europe/Kaliningrad	Moscow-01 - Kaliningrad
 RU	+5545+03735	Europe/Moscow	Moscow+00 - west Russia
-RU	+5312+05009	Europe/Kuybyshev	Moscow+01 - Caspian Sea
+RU	+5312+05009	Europe/Samara	Moscow+01 - Caspian Sea
 RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
 RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
 RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
 RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
-RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Irkutsk
+RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
 RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
-RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Vladivostok
+RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Amur River
 RU	+5934+15048	Asia/Magadan	Moscow+08 - Magadan & Sakhalin
 RU	+5301+15839	Asia/Kamchatka	Moscow+09 - Kamchatka
 RU	+6445+17729	Asia/Anadyr	Moscow+10 - Bering Sea