Landed NSPRPUB_RELEASE_4_0_20000223 onto the main trunk.
authorwtc%netscape.com
Wed, 23 Feb 2000 23:38:19 +0000
changeset 1204 e4d8a15c51158af9808e53c5c3ec90954f504042
parent 1199 bf09a4fbda050adc19711f5e2262885bd06c5d08
child 1205 eff63d581005656c57baf0e061a0989631049da0
child 1213 1dfc204971237e5800f72b38d526ef06168a65f9
child 1389 0f5d7cbe75a50aab1b2748bfc18b7e1184512457
child 1474 95ee226c8f372c591d8c763a34c7871b8087b1da
child 1565 3e602adf6934a151fea75989df8aa266e3577dde
child 1571 868f8cb95ea3f3db8f866910d4ef473b23529bc2
child 1614 b8a188925bdf91f75fd6b0459b773bb6765260c7
child 1634 3b5285bb62ac983bb3f005206830abb314b131f5
child 1724 486d3df5e5b7313d6e96110be0f7d7646c1b2334
child 1831 1a11308849cd5cb6dfb00a82b03476363707987a
child 1832 0797b5c7446c64a9f2cd5e192c5d28752fe63b96
child 1906 b3c54778df54745293b26e5b744b359e11e03bbe
child 1907 fb58750a3519af949192761c77d05c1852a7f4d9
child 1908 dbdc9b23327ffa95142d655eb45d0ffc95e39200
child 1931 4b7a0d952b434c2523be847e590372dba60a6908
child 1933 53d34f9e5f4fc0f68a81207c7a211dc57bbc7a5b
child 2004 e3b9fbe16b6f730d0604ca9e393be438b52da19e
child 2005 5d06e36342e8ddbc4b12e82ca2f3d16b4413c393
push idunknown
push userunknown
push dateunknown
Landed NSPRPUB_RELEASE_4_0_20000223 onto the main trunk.
Makefile
Makefile.in
config/Linux.mk
config/autoconf.mk.in
config/module.df
config/prdepend.h
config/rules.mk
configure
configure.in
lib/Makefile
lib/Makefile.in
lib/ds/plds.rc
lib/ds/plvrsion.c
lib/libc/src/plc.rc
lib/libc/src/plvrsion.c
lib/prstreams/plvrsion.c
lib/prstreams/prstrms.cpp
lib/prstreams/prstrms.h
lib/prstreams/prstrms.rc
macbuild/NSPR20PPC.mcp
makefile.win
pr/include/MANIFEST
pr/include/md/_aix.h
pr/include/md/_aix32.cfg
pr/include/md/_aix32in6.cfg
pr/include/md/_aix64.cfg
pr/include/md/_beos.h
pr/include/md/_hpux.h
pr/include/md/_hpux32.cfg
pr/include/md/_hpux64.cfg
pr/include/md/_irix.h
pr/include/md/_irix32.cfg
pr/include/md/_irix64.cfg
pr/include/md/_linux.cfg
pr/include/md/_linux.h
pr/include/md/_macos.h
pr/include/md/_os2.h
pr/include/md/_osf1.cfg
pr/include/md/_osf1.h
pr/include/md/_solaris.h
pr/include/md/_solaris32.cfg
pr/include/md/_solaris64.cfg
pr/include/md/_unixos.h
pr/include/md/_unixware7.cfg
pr/include/md/_win95.cfg
pr/include/md/_win95.h
pr/include/md/_winnt.cfg
pr/include/md/_winnt.h
pr/include/nspr.h
pr/include/obsolete/probslet.h
pr/include/prerr.h
pr/include/prinit.h
pr/include/prio.h
pr/include/pripcsem.h
pr/include/private/pprio.h
pr/include/private/primpl.h
pr/include/prnetdb.h
pr/include/prrng.h
pr/include/prshm.h
pr/include/prtpool.h
pr/include/prtypes.h
pr/include/prvrsion.h
pr/src/Makefile
pr/src/Makefile.in
pr/src/io/Makefile
pr/src/io/Makefile.in
pr/src/io/prdir.c
pr/src/io/prfdcach.c
pr/src/io/prfile.c
pr/src/io/priometh.c
pr/src/io/pripv6.c
pr/src/io/prlayer.c
pr/src/io/prpolevt.c
pr/src/io/prsocket.c
pr/src/linking/prlink.c
pr/src/md/mac/macsocket.h
pr/src/md/mac/macsockotpt.c
pr/src/md/mac/prcpucfg.h
pr/src/md/windows/Makefile
pr/src/md/windows/ntio.c
pr/src/md/windows/ntsec.c
pr/src/md/windows/ntthread.c
pr/src/md/windows/w32ipcsem.c
pr/src/md/windows/w32shm.c
pr/src/md/windows/w95io.c
pr/src/md/windows/w95thred.c
pr/src/md/windows/win32_errors.c
pr/src/misc/prerr.c
pr/src/misc/prerr.et
pr/src/misc/prerr.properties
pr/src/misc/prerror.c
pr/src/misc/prinit.c
pr/src/misc/prnetdb.c
pr/src/misc/prtpool.c
pr/src/nspr.rc
pr/src/prvrsion.c
pr/src/pthreads/ptio.c
pr/src/pthreads/ptsynch.c
pr/src/pthreads/ptthread.c
pr/tests/Makefile
pr/tests/Makefile.in
pr/tests/accept.c
pr/tests/acceptread.c
pr/tests/addrstr.c
pr/tests/affinity.c
pr/tests/cltsrv.c
pr/tests/gethost.c
pr/tests/ipv6.c
pr/tests/lltest.c
pr/tests/makedir.c
pr/tests/mbcs.c
pr/tests/nonblock.c
pr/tests/ntioto.c
pr/tests/ntoh.c
pr/tests/op_excl.c
pr/tests/openfile.c
pr/tests/poll_nm.c
pr/tests/provider.c
pr/tests/runtests.ksh
pr/tests/semaping.c
pr/tests/semapong.c
pr/tests/server_test.c
pr/tests/servr_kk.c
pr/tests/servr_ku.c
pr/tests/servr_uk.c
pr/tests/servr_uu.c
pr/tests/socket.c
pr/tests/sockopt.c
pr/tests/thrpool_client.c
pr/tests/thrpool_server.c
pr/tests/thruput.c
pr/tests/tmoacc.c
pr/tests/tmocon.c
pr/tests/vercheck.c
pr/tests/version.c
--- a/Makefile
+++ b/Makefile
@@ -96,10 +96,10 @@ endif
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/imports.df; \
 	cd $(OBJDIR_NAME); \
 	cp -f mdbinary.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdbinary.jar; \
 	cd include; \
 	cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdheader.jar
 
-depend: clean
+depend:
 	@echo "NSPR20 has no dependencies.  Skipped."
--- a/Makefile.in
+++ b/Makefile.in
@@ -101,10 +101,10 @@ endif
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/imports.df; \
 	cd $(OBJDIR_NAME); \
 	cp -f mdbinary.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdbinary.jar; \
 	cd include; \
 	cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdheader.jar
 
-depend: clean
+depend:
 	@echo "NSPR20 has no dependencies.  Skipped."
--- a/config/Linux.mk
+++ b/config/Linux.mk
@@ -42,16 +42,18 @@ ifeq ($(CLASSIC_NSPR),1)
 IMPL_STRATEGY		= _EMU
 DEFINES			+= -D_PR_LOCAL_THREADS_ONLY
 else
 USE_PTHREADS		= 1
 IMPL_STRATEGY		= _PTH
 DEFINES			+= -D_REENTRANT
 endif
 
+USE_IPV6 = 1
+
 ifeq (86,$(findstring 86,$(OS_TEST)))
 CPU_ARCH		:= x86
 else
 ifeq (,$(filter-out armv4l sa110,$(OS_TEST)))
 CPU_ARCH		:= arm
 else
 CPU_ARCH		:= $(OS_TEST)
 endif
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -21,16 +21,17 @@ PTHREADS_USER	= @USE_USER_PTHREADS@
 CLASSIC_NSPR	= @USE_NSPR_THREADS@
 
 AS		= @AS@
 ASFLAGS		= @ASFLAGS@
 CC		= @CC@
 CCC		= @CXX@
 AR		= @AR@
 AR_FLAGS	= @AR_FLAGS@
+LD		= @LD@
 RANLIB		= @RANLIB@
 PERL		= @PERL@
 DLLTOOL		= @DLLTOOL@
 WINDRES		= @WINDRES@
 RC		= $(WINDRES)
 
 OS_CFLAGS	= @CFLAGS@ $(DSO_CFLAGS)
 OS_CXXFLAGS	= @CXXFLAGS@ $(DSO_CFLAGS)
--- a/config/module.df
+++ b/config/module.df
@@ -15,9 +15,9 @@
 # Reserved.
 #
 
 # Module description file
 #
 # A module is also called a component or a subsystem.
 
 MOD_NAME = nspr20
-MOD_VERSION = 3
+MOD_VERSION = 4
--- a/config/prdepend.h
+++ b/config/prdepend.h
@@ -18,8 +18,9 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSPR in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
+
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -57,24 +57,22 @@ srcdir=.
 endif
 
 ifndef NSPR_CONFIG_MK
 include $(topsrcdir)/config/config.mk
 endif
 
 ifdef USE_AUTOCONF
 ifdef INTERNAL_TOOLS
-ifdef CROSS_COMPILE
 CC=$(HOST_CC)
 CCC=$(HOST_CXX)
 CFLAGS=$(HOST_CFLAGS)
 CXXFLAGS=$(HOST_CXXFLAGS)
 endif
 endif
-endif
 
 #
 # This makefile contains rules for building the following kinds of
 # libraries:
 # - LIBRARY: a static (archival) library
 # - SHARED_LIBRARY: a shared (dynamic link) library
 # - IMPORT_LIBRARY: an import library, used only on Windows and OS/2
 #
@@ -405,16 +403,39 @@ endif
 	$(AS) -o $@ $(ASFLAGS) -c $<
 
 %.i: %.c
 	$(CC) -C -E $(CFLAGS) $< > $*.i
 
 %: %.pl
 	rm -f $@; cp $< $@; chmod +x $@
 
+#
+# HACK ALERT
+#
+# The only purpose of this rule is to pass Mozilla's Tinderbox depend
+# builds (http://tinderbox.mozilla.org/showbuilds.cgi).  Mozilla's
+# Tinderbox builds NSPR continuously as part of the Mozilla client.
+# Because NSPR's make depend is not implemented, whenever we change
+# an NSPR header file, the depend build does not recompile the NSPR
+# files that depend on the header.
+#
+# This rule makes all the objects depend on a dummy header file.
+# Touch this dummy header file to force the depend build to recompile
+# everything.
+#
+# This rule should be removed when make depend is implemented.
+#
+
+DUMMY_DEPEND_H = $(topsrcdir)/config/prdepend.h
+
+$(filter $(OBJDIR)/%.$(OBJ_SUFFIX),$(OBJS)): $(OBJDIR)/%.$(OBJ_SUFFIX): $(DUMMY_DEPEND_H)
+
+# END OF HACK
+
 ################################################################################
 # Special gmake rules.
 ################################################################################
 
 #
 # Re-define the list of default suffixes, so gmake won't have to churn through
 # hundreds of built-in suffix rules for stuff we don't need.
 #
--- a/configure
+++ b/configure
@@ -688,17 +688,17 @@ echo "configure:674: checking cached sys
 
 
 
 cat >> confdefs.h <<\EOF
 #define USE_AUTOCONF 1
 EOF
 
 
-NSPR_VERSION=3
+NSPR_VERSION=4
 NSPR_MODNAME=nspr20
 _HAVE_PTHREADS=
 USE_PTHREADS=
 USE_USER_PTHREADS=
 USE_NSPR_THREADS=
 USE_N32=
 USE_64=
 USE_CPLUS=
@@ -1485,23 +1485,60 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
 test -n "$AS" && break
 done
 test -n "$AS" || AS=":"
 
     fi
+    if test -z "$LD"; then
+	    for ac_prog in "${target_alias}-ld" "${target}-ld"
+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:1500: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$LD"; then
+  ac_cv_prog_LD="$LD" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_LD="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+LD="$ac_cv_prog_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LD" && break
+done
+test -n "$LD" || LD=":"
+
+    fi
     if test -z "$DLLTOOL"; then
 	    for ac_prog in "${target_alias}-dlltool" "${target}-dlltool"
 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:1500: checking for $ac_word" >&5
+echo "configure:1537: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$DLLTOOL"; then
   ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
 else
   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
   ac_dummy="$PATH"
@@ -1528,17 +1565,17 @@ test -n "$DLLTOOL" || DLLTOOL=":"
 
     fi
     if test -z "$WINDRES"; then
 	    for ac_prog in "${target_alias}-windres" "${target}-windres"
 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:1537: checking for $ac_word" >&5
+echo "configure:1574: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$WINDRES"; then
   ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test.
 else
   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
   ac_dummy="$PATH"
@@ -1563,17 +1600,17 @@ test -n "$WINDRES" && break
 done
 test -n "$WINDRES" || WINDRES=":"
 
     fi
 else
     # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1572: checking for $ac_word" >&5
+echo "configure:1609: 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
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
   ac_dummy="$PATH"
@@ -1593,17 +1630,17 @@ if test -n "$CC"; then
 else
   echo "$ac_t""no" 1>&6
 fi
 
 if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1602: checking for $ac_word" >&5
+echo "configure:1639: 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
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
   ac_prog_rejected=no
@@ -1644,17 +1681,17 @@ else
 fi
 
   if test -z "$CC"; then
     case "`uname -s`" in
     *win32* | *WIN32*)
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1653: checking for $ac_word" >&5
+echo "configure:1690: 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
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
   ac_dummy="$PATH"
@@ -1676,33 +1713,33 @@ else
 fi
  ;;
     esac
   fi
   test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1685: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1722: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
 ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
 cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 1696 "configure"
+#line 1733 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:1701: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1738: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
     ac_cv_prog_cc_cross=no
   else
     ac_cv_prog_cc_cross=yes
   fi
 else
@@ -1718,31 +1755,31 @@ ac_compile='${CC-cc} -c $CFLAGS $CPPFLAG
 ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
 if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1727: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1764: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1732: checking whether we are using GNU C" >&5
+echo "configure:1769: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
 #ifdef __GNUC__
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1741: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1778: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
 fi
 fi
 
 echo "$ac_t""$ac_cv_prog_gcc" 1>&6
 
@@ -1751,17 +1788,17 @@ if test $ac_cv_prog_gcc = yes; then
 else
   GCC=
 fi
 
 ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1760: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1797: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   echo 'void f(){}' > conftest.c
 if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
   ac_cv_prog_cc_g=yes
 else
   ac_cv_prog_cc_g=no
@@ -1787,17 +1824,17 @@ else
   fi
 fi
 
     for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
 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:1796: checking for $ac_word" >&5
+echo "configure:1833: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test -n "$CXX"; then
   ac_cv_prog_CXX="$CXX" # Let the user override the test.
 else
   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
   ac_dummy="$PATH"
@@ -1819,33 +1856,33 @@ else
 fi
 
 test -n "$CXX" && break
 done
 test -n "$CXX" || CXX="gcc"
 
 
 echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1828: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+echo "configure:1865: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
 
 ac_ext=C
 # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
 ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
 cross_compiling=$ac_cv_prog_cxx_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 1839 "configure"
+#line 1876 "configure"
 #include "confdefs.h"
 
 int main(){return(0);}
 EOF
-if { (eval echo configure:1844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cxx_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
     ac_cv_prog_cxx_cross=no
   else
     ac_cv_prog_cxx_cross=yes
   fi
 else
@@ -1861,31 +1898,31 @@ ac_compile='${CC-cc} -c $CFLAGS $CPPFLAG
 ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
 if test $ac_cv_prog_cxx_works = no; then
   { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1870: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1907: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
 cross_compiling=$ac_cv_prog_cxx_cross
 
 echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-echo "configure:1875: checking whether we are using GNU C++" >&5
+echo "configure:1912: checking whether we are using GNU C++" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.C <<EOF
 #ifdef __GNUC__
   yes;
 #endif
 EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1884: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1921: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gxx=yes
 else
   ac_cv_prog_gxx=no
 fi
 fi
 
 echo "$ac_t""$ac_cv_prog_gxx" 1>&6
 
@@ -1894,17 +1931,17 @@ if test $ac_cv_prog_gxx = yes; then
 else
   GXX=
 fi
 
 ac_test_CXXFLAGS="${CXXFLAGS+set}"
 ac_save_CXXFLAGS="$CXXFLAGS"
 CXXFLAGS=
 echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-echo "configure:1903: checking whether ${CXX-g++} accepts -g" >&5
+echo "configure:1940: checking whether ${CXX-g++} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   echo 'void f(){}' > conftest.cc
 if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
   ac_cv_prog_cxx_g=yes
 else
   ac_cv_prog_cxx_g=no
@@ -1928,17 +1965,17 @@ else
   else
     CXXFLAGS=
   fi
 fi
 
     # 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:1937: checking for $ac_word" >&5
+echo "configure:1974: 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
   if test -n "$RANLIB"; then
   ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
 else
   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
   ac_dummy="$PATH"
@@ -1960,17 +1997,17 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
     for ac_prog in as
 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:1969: checking for $ac_word" >&5
+echo "configure:2006: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_AS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$AS" in
   /*)
   ac_cv_path_AS="$AS" # Let the user override the test with a path.
   ;;
   ?:/*)			 
@@ -2001,17 +2038,17 @@ test -n "$AS" && break
 done
 test -n "$AS" || AS="$CC"
 
     for ac_prog in ar
 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:2010: checking for $ac_word" >&5
+echo "configure:2047: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$AR" in
   /*)
   ac_cv_path_AR="$AR" # Let the user override the test with a path.
   ;;
   ?:/*)			 
@@ -2037,22 +2074,63 @@ if test -n "$AR"; then
 else
   echo "$ac_t""no" 1>&6
 fi
 
 test -n "$AR" && break
 done
 test -n "$AR" || AR=":"
 
+    for ac_prog in ld
+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:2088: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$LD" in
+  /*)
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_LD="$LD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_LD="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LD" && break
+done
+test -n "$LD" || LD=":"
+
     for ac_prog in dlltool
 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:2051: checking for $ac_word" >&5
+echo "configure:2129: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_DLLTOOL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$DLLTOOL" in
   /*)
   ac_cv_path_DLLTOOL="$DLLTOOL" # Let the user override the test with a path.
   ;;
   ?:/*)			 
@@ -2083,17 +2161,17 @@ test -n "$DLLTOOL" && break
 done
 test -n "$DLLTOOL" || DLLTOOL=":"
 
     for ac_prog in windres
 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:2092: checking for $ac_word" >&5
+echo "configure:2170: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_WINDRES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$WINDRES" in
   /*)
   ac_cv_path_WINDRES="$WINDRES" # Let the user override the test with a path.
   ;;
   ?:/*)			 
@@ -2147,17 +2225,17 @@ rm -f a.out
 # SunOS /usr/etc/install
 # IRIX /sbin/install
 # AIX /bin/install
 # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
 # AFS /usr/afsws/bin/install, which mishandles nonexistent args
 # 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:2156: checking for a BSD compatible install" >&5
+echo "configure:2234: 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
 else
     IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
   for ac_dir in $PATH; do
     # Account for people who put trailing slashes in PATH elements.
     case "$ac_dir/" in
@@ -2200,17 +2278,17 @@ echo "$ac_t""$INSTALL" 1>&6
 # It thinks the first close brace ends the variable substitution.
 test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
 test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
 
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:2209: checking whether ln -s works" >&5
+echo "configure:2287: 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
   rm -f conftestdata
 if ln -s X conftestdata 2>/dev/null
 then
   rm -f conftestdata
   ac_cv_prog_LN_S="ln -s"
@@ -2225,17 +2303,17 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
 for ac_prog in perl5 perl
 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:2234: checking for $ac_word" >&5
+echo "configure:2312: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   case "$PERL" in
   /*)
   ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
   ;;
   ?:/*)			 
@@ -2279,16 +2357,19 @@ AR_FLAGS='cr $@'
 OS_TARGET=`uname -s`
 OS_ARCH=`uname -s | sed -e 's|/|_|g'`
 OS_RELEASE=`uname -r`
 OS_TEST=`uname -m`
 
 case "$host" in
 *-mingw*)
     ;;
+*-beos*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE"
+    ;;
 *)
     HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX"
     ;;
 esac
 
 case "$target" in
 
 *-aix*)
@@ -2780,16 +2861,20 @@ EOF
     cat >> confdefs.h <<\EOF
 #define _BSD_SOURCE 1
 EOF
 
     cat >> confdefs.h <<\EOF
 #define _SVID_SOURCE 1
 EOF
 
+    cat >> confdefs.h <<\EOF
+#define LINUX 1
+EOF
+
     CFLAGS="$CFLAGS -pipe -ansi"
     CXXFLAGS="$CXXFLAGS -pipe -ansi"
     MDCPUCFG_H=_linux.cfg
     PR_MD_CSRCS=linux.c
     MKSHLIB='$(LD) $(DSO_LDOPTS) -soname $(notdir $@) -o $@'
     DSO_CFLAGS=-fPIC
     DSO_LDOPTS=-shared
     case "${target_cpu}" in
@@ -2817,16 +2902,20 @@ EOF
     esac    
     ;;
 
 *-mingw*)
     cat >> confdefs.h <<\EOF
 #define XP_PC 1
 EOF
 
+    cat >> confdefs.h <<\EOF
+#define NONAMELESSUNION 1
+EOF
+
     PR_MD_ARCH_DIR=windows
     if test -z "$GNU_CC"; then
 	    OBJ_SUFFIX=obj
 	    LIB_SUFFIX=lib
 	    DLL_SUFFIX=dll
     fi
     MKSHLIB='$(DLLTOOL) --as=$(AS) -k --dllname $*.dll --output-lib $@'
 
@@ -3019,72 +3108,72 @@ esac
 if test "$enable_shared" = no; then
     MKSHLIB=
 fi
 
 
 
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:3028: checking how to run the C preprocessor" >&5
+echo "configure:3117: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
 if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     # This must be in double quotes, not single quotes, because CPP may get
   # substituted into the Makefile and "${CC-cc}" will confuse make.
   CPP="${CC-cc} -E"
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 3043 "configure"
+#line 3132 "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:3049: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3138: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
 else
   echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 3060 "configure"
+#line 3149 "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:3066: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3155: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
 else
   echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 3077 "configure"
+#line 3166 "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:3083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
 else
   echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
@@ -3100,23 +3189,23 @@ fi
   CPP="$ac_cv_prog_CPP"
 else
   ac_cv_prog_CPP="$CPP"
 fi
 echo "$ac_t""$CPP" 1>&6
 
 if test $ac_cv_prog_gcc = yes; then
     echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
-echo "configure:3109: checking whether ${CC-cc} needs -traditional" >&5
+echo "configure:3198: checking whether ${CC-cc} needs -traditional" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     ac_pattern="Autoconf.*'x'"
   cat > conftest.$ac_ext <<EOF
-#line 3115 "configure"
+#line 3204 "configure"
 #include "confdefs.h"
 #include <sgtty.h>
 Autoconf TIOCGETP
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   egrep "$ac_pattern" >/dev/null 2>&1; then
   rm -rf conftest*
   ac_cv_prog_gcc_traditional=yes
@@ -3124,17 +3213,17 @@ else
   rm -rf conftest*
   ac_cv_prog_gcc_traditional=no
 fi
 rm -f conftest*
 
 
   if test $ac_cv_prog_gcc_traditional = no; then
     cat > conftest.$ac_ext <<EOF
-#line 3133 "configure"
+#line 3222 "configure"
 #include "confdefs.h"
 #include <termio.h>
 Autoconf TCGETA
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   egrep "$ac_pattern" >/dev/null 2>&1; then
   rm -rf conftest*
   ac_cv_prog_gcc_traditional=yes
@@ -3148,22 +3237,22 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional
   if test $ac_cv_prog_gcc_traditional = yes; then
     CC="$CC -traditional"
   fi
 fi
 
 for ac_func in lchown strerror
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3157: checking for $ac_func" >&5
+echo "configure:3246: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3162 "configure"
+#line 3251 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
 #include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char $ac_func();
@@ -3176,17 +3265,17 @@ int main() {
 #if defined (__stub_$ac_func) || defined (__stub___$ac_func)
 choke me
 #else
 $ac_func();
 #endif
 
 ; return 0; }
 EOF
-if { (eval echo configure:3185: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=no"
 fi
@@ -3204,36 +3293,36 @@ else
   echo "$ac_t""no" 1>&6
 fi
 done
 
 
 
 
 echo $ac_n "checking for pthread_attr_init in -lpthread""... $ac_c" 1>&6
-echo "configure:3213: checking for pthread_attr_init in -lpthread" >&5
+echo "configure:3302: checking for pthread_attr_init in -lpthread" >&5
 ac_lib_var=`echo pthread'_'pthread_attr_init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lpthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3221 "configure"
+#line 3310 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_attr_init();
 
 int main() {
 pthread_attr_init()
 ; return 0; }
 EOF
-if { (eval echo configure:3232: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
@@ -3242,36 +3331,36 @@ LIBS="$ac_save_LIBS"
 
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread"
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for pthread_attr_init in -lc_r""... $ac_c" 1>&6
-echo "configure:3251: checking for pthread_attr_init in -lc_r" >&5
+echo "configure:3340: checking for pthread_attr_init in -lc_r" >&5
 ac_lib_var=`echo c_r'_'pthread_attr_init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lc_r  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3259 "configure"
+#line 3348 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_attr_init();
 
 int main() {
 pthread_attr_init()
 ; return 0; }
 EOF
-if { (eval echo configure:3270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
@@ -3280,36 +3369,36 @@ LIBS="$ac_save_LIBS"
 
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r"
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for pthread_attr_init in -lc""... $ac_c" 1>&6
-echo "configure:3289: checking for pthread_attr_init in -lc" >&5
+echo "configure:3378: checking for pthread_attr_init in -lc" >&5
 ac_lib_var=`echo c'_'pthread_attr_init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3297 "configure"
+#line 3386 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_attr_init();
 
 int main() {
 pthread_attr_init()
 ; return 0; }
 EOF
-if { (eval echo configure:3308: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
@@ -3426,17 +3515,17 @@ if test "${enable_ipv6+set}" = set; then
       fi
 fi
 
 
 if test -n "$USE_PTHREADS"; then
       rm -f conftest*
    ac_cv_have_dash_pthread=no
    echo $ac_n "checking whether ${CC-cc} accepts -pthread""... $ac_c" 1>&6
-echo "configure:3435: checking whether ${CC-cc} accepts -pthread" >&5
+echo "configure:3524: checking whether ${CC-cc} accepts -pthread" >&5
    echo 'int main() { return 0; }' | cat > conftest.c
    ${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1
    if test $? -eq 0; then
 	if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthread`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then
 	    ac_cv_have_dash_pthread=yes
 	    CFLAGS="$CFLAGS -pthread"
 	    CXXFLAGS="$CXXFLAGS -pthread"
 	fi
@@ -3496,22 +3585,22 @@ EOF
 	    cat >> confdefs.h <<\EOF
 #define _REENTRANT 1
 EOF
 
 	    ;;
     esac
 
     echo $ac_n "checking for pthread_create""... $ac_c" 1>&6
-echo "configure:3505: checking for pthread_create" >&5
+echo "configure:3594: checking for pthread_create" >&5
 if eval "test \"`echo '$''{'ac_cv_func_pthread_create'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3510 "configure"
+#line 3599 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char pthread_create(); below.  */
 #include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_create();
@@ -3524,17 +3613,17 @@ int main() {
 #if defined (__stub_pthread_create) || defined (__stub___pthread_create)
 choke me
 #else
 pthread_create();
 #endif
 
 ; return 0; }
 EOF
-if { (eval echo configure:3533: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3622: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_pthread_create=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_func_pthread_create=no"
 fi
@@ -3543,36 +3632,36 @@ fi
 
 if eval "test \"`echo '$ac_cv_func_'pthread_create`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   :
 else
   echo "$ac_t""no" 1>&6
 
        echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
-echo "configure:3552: checking for pthread_create in -lpthread" >&5
+echo "configure:3641: checking for pthread_create in -lpthread" >&5
 ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lpthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3560 "configure"
+#line 3649 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_create();
 
 int main() {
 pthread_create()
 ; return 0; }
 EOF
-if { (eval echo configure:3571: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
@@ -3661,22 +3750,22 @@ EOF
                 PR_MD_ASFILES="$PR_MD_ASFILES os_SunOS_32.s"
             fi
         fi
     fi
     ;;
 esac
 
 echo $ac_n "checking for dlopen""... $ac_c" 1>&6
-echo "configure:3670: checking for dlopen" >&5
+echo "configure:3759: checking for dlopen" >&5
 if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3675 "configure"
+#line 3764 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char dlopen(); below.  */
 #include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char dlopen();
@@ -3689,17 +3778,17 @@ int main() {
 #if defined (__stub_dlopen) || defined (__stub___dlopen)
 choke me
 #else
 dlopen();
 #endif
 
 ; return 0; }
 EOF
-if { (eval echo configure:3698: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_dlopen=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_func_dlopen=no"
 fi
@@ -3708,36 +3797,36 @@ fi
 
 if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   :
 else
   echo "$ac_t""no" 1>&6
 
     echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:3717: checking for dlopen in -ldl" >&5
+echo "configure:3806: checking for dlopen in -ldl" >&5
 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-ldl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3725 "configure"
+#line 3814 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char dlopen();
 
 int main() {
 dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:3736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
@@ -3821,16 +3910,17 @@ fi
 
 
 
 
 
 
 
 
+
 trap '' 1 2 15
 cat > confcache <<\EOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
 # scripts and configure runs.  It is not useful on other systems.
 # If it contains results you don't want to keep, you may remove or edit it.
 #
 # By default, configure uses ./config.cache as the cache file,
@@ -4031,16 +4121,17 @@ s%@build_vendor@%$build_vendor%g
 s%@build_os@%$build_os%g
 s%@WHOAMI@%$WHOAMI%g
 s%@HOST_CC@%$HOST_CC%g
 s%@CC@%$CC%g
 s%@CXX@%$CXX%g
 s%@RANLIB@%$RANLIB%g
 s%@AR@%$AR%g
 s%@AS@%$AS%g
+s%@LD@%$LD%g
 s%@DLLTOOL@%$DLLTOOL%g
 s%@WINDRES@%$WINDRES%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
 s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
 s%@INSTALL_DATA@%$INSTALL_DATA%g
 s%@LN_S@%$LN_S%g
 s%@PERL@%$PERL%g
 s%@CPP@%$CPP%g
--- a/configure.in
+++ b/configure.in
@@ -35,17 +35,17 @@ AC_VALIDATE_CACHED_SYSTEM_TUPLE
 AC_PREFIX_DEFAULT(\${MOD_DEPTH}/dist)
 
 dnl Set this define to make fixes w/o breaking anything else.
 AC_DEFINE(USE_AUTOCONF)
 
 dnl ========================================================
 dnl = Defaults
 dnl ========================================================
-NSPR_VERSION=3
+NSPR_VERSION=4
 NSPR_MODNAME=nspr20
 _HAVE_PTHREADS=
 USE_PTHREADS=
 USE_USER_PTHREADS=
 USE_NSPR_THREADS=
 USE_N32=
 USE_64=
 USE_CPLUS=
@@ -190,28 +190,32 @@ if test "$target" != "$host"; then
 	    AC_CHECK_PROGS(RANLIB, "${target_alias}-ranlib" "${target}-ranlib", :)
     fi
     if test -z "$AR"; then
 	    AC_CHECK_PROGS(AR, "${target_alias}-ar" "${target}-ar", :)
     fi
     if test -z "$AS"; then
 	    AC_CHECK_PROGS(AS, "${target_alias}-as" "${target}-as", :)
     fi
+    if test -z "$LD"; then
+	    AC_CHECK_PROGS(LD, "${target_alias}-ld" "${target}-ld", :)
+    fi
     if test -z "$DLLTOOL"; then
 	    AC_CHECK_PROGS(DLLTOOL, "${target_alias}-dlltool" "${target}-dlltool", :)
     fi
     if test -z "$WINDRES"; then
 	    AC_CHECK_PROGS(WINDRES, "${target_alias}-windres" "${target}-windres", :)
     fi
 else
     AC_PROG_CC
     AC_PROG_CXX
     AC_PROG_RANLIB
     AC_PATH_PROGS(AS, as, $CC)
     AC_PATH_PROGS(AR, ar, :)
+    AC_PATH_PROGS(LD, ld, :)
     AC_PATH_PROGS(DLLTOOL, dlltool, :)
     AC_PATH_PROGS(WINDRES, windres, :)
     if test -z "$HOST_CC"; then
 	    HOST_CC="$CC"
     fi
     if test -z "$HOST_CFLAGS"; then
 	    HOST_CFLAGS="$CFLAGS"
     fi
@@ -250,16 +254,19 @@ OS_RELEASE=`uname -r`
 OS_TEST=`uname -m`
 
 dnl ========================================================
 dnl Override of system specific host options
 dnl ========================================================
 case "$host" in
 *-mingw*)
     ;;
+*-beos*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE"
+    ;;
 *)
     HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX"
     ;;
 esac
 
 dnl ========================================================
 dnl Override of system specific target options
 dnl ========================================================
@@ -550,16 +557,17 @@ case "$target" in
     esac
     ;;
 
 *-linux*)
     AC_DEFINE(XP_UNIX)
     AC_DEFINE(_POSIX_SOURCE)
     AC_DEFINE(_BSD_SOURCE)
     AC_DEFINE(_SVID_SOURCE)
+    AC_DEFINE(LINUX)
     CFLAGS="$CFLAGS -pipe -ansi"
     CXXFLAGS="$CXXFLAGS -pipe -ansi"
     MDCPUCFG_H=_linux.cfg
     PR_MD_CSRCS=linux.c
     MKSHLIB='$(LD) $(DSO_LDOPTS) -soname $(notdir $@) -o $@'
     DSO_CFLAGS=-fPIC
     DSO_LDOPTS=-shared
     case "${target_cpu}" in
@@ -578,16 +586,17 @@ case "$target" in
     *)
         _OPTIMIZE_FLAGS=-O2
         ;;
     esac    
     ;;
 
 *-mingw*)
     AC_DEFINE(XP_PC)
+    AC_DEFINE(NONAMELESSUNION)
     PR_MD_ARCH_DIR=windows
     if test -z "$GNU_CC"; then
 	    OBJ_SUFFIX=obj
 	    LIB_SUFFIX=lib
 	    DLL_SUFFIX=dll
     fi
     MKSHLIB='$(DLLTOOL) --as=$(AS) -k --dllname $*.dll --output-lib $@'
 
@@ -1046,16 +1055,17 @@ AC_SUBST(OS_RELEASE)
 AC_SUBST(OS_TEST)
 
 AC_SUBST(DEFINES)
 AC_SUBST(DEFS)
 AC_SUBST(AR)
 AC_SUBST(AR_FLAGS)
 AC_SUBST(AS)
 AC_SUBST(ASFLAGS)
+AC_SUBST(LD)
 AC_SUBST(DLLTOOL)
 AC_SUBST(WINDRES)
 AC_SUBST(RANLIB)
 AC_SUBST(PERL)
 
 AC_SUBST(OS_LIBS)
 AC_SUBST(RESOLVE_LINK_SYMBOLS)
 AC_SUBST(AIX_LINK_OPTS)
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,17 +20,13 @@
 MOD_DEPTH = ..
 
 export NSPR20=1
 
 include $(MOD_DEPTH)/config/config.mk
 
 DIRS = ds libc
 
-ifneq (,$(filter-out Rhapsody WIN16 NEWS-OS,$(OS_TARGET)))
-DIRS += prstreams
-endif
-
 include $(MOD_DEPTH)/config/rules.mk
 
 export:: $(TARGETS)
 
 install:: export
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -25,17 +25,13 @@ VPATH		= @srcdir@
 include $(MOD_DEPTH)/config/autoconf.mk
 
 export NSPR20=1
 
 include $(topsrcdir)/config/config.mk
 
 DIRS = ds libc
 
-ifneq (,$(filter-out Rhapsody WIN16 NEWS-OS,$(OS_TARGET)))
-DIRS += prstreams
-endif
-
 include $(topsrcdir)/config/rules.mk
 
 export:: $(TARGETS)
 
 install:: export
--- a/lib/ds/plds.rc
+++ b/lib/ds/plds.rc
@@ -17,16 +17,20 @@
  */
 
 #include "prinit.h"
 #include <winver.h>
 
 #define MY_LIBNAME "plds"
 #define MY_FILEDESCRIPTION "PLDS Library"
 
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
 #ifdef _DEBUG
 #define MY_DEBUG_STR " (debug)"
 #define MY_FILEFLAGS_1 VS_FF_DEBUG
 #else
 #define MY_DEBUG_STR ""
 #define MY_FILEFLAGS_1 0x0L
 #endif
 #if PR_BETA
@@ -61,17 +65,17 @@ BEGIN
     BLOCK "StringFileInfo"
     BEGIN
         BLOCK "040904B0" // Lang=US English, CharSet=Unicode
         BEGIN
             VALUE "CompanyName", "Netscape Communications Corporation\0"
             VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
             VALUE "FileVersion", PR_VERSION "\0"
             VALUE "InternalName", MY_INTERNAL_NAME "\0"
-            VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+            VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
             VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
             VALUE "ProductName", "Netscape Portable Runtime\0"
             VALUE "ProductVersion", PR_VERSION "\0"
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x409, 1200
--- a/lib/ds/plvrsion.c
+++ b/lib/ds/plvrsion.c
@@ -37,17 +37,24 @@
 #define _PRODUCTION ""
 #endif
 #if defined(DEBUG)
 #define _DEBUG_STRING " (debug)"
 #else
 #define _DEBUG_STRING ""
 #endif
 
-PRVersionDescription prVersionDescription_libplds3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplds, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
 {
     /* version          */  2,                  /* this is the only one supported */
     /* buildTime        */  _BUILD_TIME,        /* usecs since midnight 1/1/1970 GMT */
     /* buildTimeString  */  _BUILD_STRING,       /*    ditto, but human readable */
     /* vMajor           */  PR_VMAJOR,          /* NSPR's version number */
     /* vMinor           */  PR_VMINOR,          /*  and minor version */
     /* vPatch           */  PR_VPATCH,          /*  and patch */
     /* beta             */  PR_BETA,            /* beta build boolean */
@@ -87,13 +94,13 @@ PR_IMPLEMENT(const PRVersionDescription*
      * Add dummy references to rcsid and sccsid to prevent them
      * from being optimized away as unused variables.
      */
     const char *dummy;
     
     dummy = rcsid;
     dummy = sccsid;
 #endif
-    return &prVersionDescription_libplds3;
+    return &VERSION_DESC_NAME;
 }  /* versionEntryPointType */
 
 /* plvrsion.c */
 
--- a/lib/libc/src/plc.rc
+++ b/lib/libc/src/plc.rc
@@ -17,16 +17,20 @@
  */
 
 #include "prinit.h"
 #include <winver.h>
 
 #define MY_LIBNAME "plc"
 #define MY_FILEDESCRIPTION "PLC Library"
 
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
 #ifdef _DEBUG
 #define MY_DEBUG_STR " (debug)"
 #define MY_FILEFLAGS_1 VS_FF_DEBUG
 #else
 #define MY_DEBUG_STR ""
 #define MY_FILEFLAGS_1 0x0L
 #endif
 #if PR_BETA
@@ -61,17 +65,17 @@ BEGIN
     BLOCK "StringFileInfo"
     BEGIN
         BLOCK "040904B0" // Lang=US English, CharSet=Unicode
         BEGIN
             VALUE "CompanyName", "Netscape Communications Corporation\0"
             VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
             VALUE "FileVersion", PR_VERSION "\0"
             VALUE "InternalName", MY_INTERNAL_NAME "\0"
-            VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+            VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
             VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
             VALUE "ProductName", "Netscape Portable Runtime\0"
             VALUE "ProductVersion", PR_VERSION "\0"
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x409, 1200
--- a/lib/libc/src/plvrsion.c
+++ b/lib/libc/src/plvrsion.c
@@ -37,17 +37,24 @@
 #define _PRODUCTION ""
 #endif
 #if defined(DEBUG)
 #define _DEBUG_STRING " (debug)"
 #else
 #define _DEBUG_STRING ""
 #endif
 
-PRVersionDescription prVersionDescription_libplc3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplc, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
 {
     /* version          */  2,                  /* this is the only one supported */
     /* buildTime        */  _BUILD_TIME,        /* usecs since midnight 1/1/1970 GMT */
     /* buildTimeString  */  _BUILD_STRING,       /*    ditto, but human readable */
     /* vMajor           */  PR_VMAJOR,          /* NSPR's version number */
     /* vMinor           */  PR_VMINOR,          /*  and minor version */
     /* vPatch           */  PR_VPATCH,          /*  and patch */
     /* beta             */  PR_BETA,            /* beta build boolean */
@@ -87,13 +94,13 @@ PR_IMPLEMENT(const PRVersionDescription*
      * Add dummy references to rcsid and sccsid to prevent them
      * from being optimized away as unused variables.
      */
     const char *dummy;
     
     dummy = rcsid;
     dummy = sccsid;
 #endif
-    return &prVersionDescription_libplc3;
+    return &VERSION_DESC_NAME;
 }  /* versionEntryPointType */
 
 /* plvrsion.c */
 
--- a/lib/prstreams/plvrsion.c
+++ b/lib/prstreams/plvrsion.c
@@ -37,17 +37,24 @@
 #define _PRODUCTION ""
 #endif
 #if defined(DEBUG)
 #define _DEBUG_STRING " (debug)"
 #else
 #define _DEBUG_STRING ""
 #endif
 
-PRVersionDescription prVersionDescription_libprstrms3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libprstrms, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
 {
     /* version          */  2,                  /* this is the only one supported */
     /* buildTime        */  _BUILD_TIME,        /* usecs since midnight 1/1/1970 GMT */
     /* buildTimeString  */  _BUILD_STRING,       /*    ditto, but human readable */
     /* vMajor           */  PR_VMAJOR,          /* NSPR's version number */
     /* vMinor           */  PR_VMINOR,          /*  and minor version */
     /* vPatch           */  PR_VPATCH,          /*  and patch */
     /* beta             */  PR_BETA,            /* beta build boolean */
@@ -87,13 +94,13 @@ PR_IMPLEMENT(const PRVersionDescription*
      * Add dummy references to rcsid and sccsid to prevent them
      * from being optimized away as unused variables.
      */
     const char *dummy;
     
     dummy = rcsid;
     dummy = sccsid;
 #endif
-    return &prVersionDescription_libprstrms3;
+    return &VERSION_DESC_NAME;
 }  /* versionEntryPointType */
 
 /* plvrsion.c */
 
--- a/lib/prstreams/prstrms.cpp
+++ b/lib/prstreams/prstrms.cpp
@@ -217,17 +217,17 @@ PRfilebuf::underflow()
 
     if ((count=PR_Read(_fd,(void *)base(),blen())) <= 0)
         return EOF;     // reached EOF
     setg(base(),base(),base()+count);
     return (int)(unsigned char) *gptr();
 }
 
 streambuf*	
-PRfilebuf::setbuf(char *buffptr, int bufflen)
+PRfilebuf::setbuf(char *buffptr, PRstreambuflen bufflen)
 {
     if (is_open() && (ebuf()))
         return 0;
     if ((!buffptr) || (bufflen <= 0))
         unbuffered(1);
     else
         setb(buffptr, buffptr+bufflen, 0);
     return this;
--- a/lib/prstreams/prstrms.h
+++ b/lib/prstreams/prstrms.h
@@ -26,16 +26,22 @@
 #include "prtypes.h"
 #include "prio.h"
 
 #ifdef _MSC_VER
 #pragma warning( disable : 4275)
 #endif
 #include <iostream.h>
 
+#if defined(AIX) && defined(__64BIT__)
+typedef long PRstreambuflen;
+#else
+typedef int PRstreambuflen;
+#endif
+
 #if defined (PRFSTREAMS_BROKEN)
 
 // fix it sometime
 
 #define	 PRfilebuf	streambuf
 #define  PRifstream	ifstream
 #define	 PRofstream	ofstream
 #define	 PRfstream	fstream
@@ -46,17 +52,17 @@ class PR_IMPLEMENT(PRfilebuf): public st
 {
 public:
     PRfilebuf();
     PRfilebuf(PRFileDesc *fd);
     PRfilebuf(PRFileDesc *fd, char * buffptr, int bufflen);
     ~PRfilebuf();
     virtual	int	overflow(int=EOF);
     virtual	int	underflow();
-    virtual	streambuf *setbuf(char *buff, int bufflen);
+    virtual	streambuf *setbuf(char *buff, PRstreambuflen bufflen);
     virtual	streampos seekoff(streamoff, ios::seek_dir, int);
     virtual int sync();
     PRfilebuf *open(const char *name, int mode, int flags);
    	PRfilebuf *attach(PRFileDesc *fd);
     PRfilebuf *close();
    	int	is_open() const {return (_fd != 0);}
     PRFileDesc *fd(){return _fd;}
 
--- a/lib/prstreams/prstrms.rc
+++ b/lib/prstreams/prstrms.rc
@@ -17,16 +17,20 @@
  */
 
 #include "prinit.h"
 #include <winver.h>
 
 #define MY_LIBNAME "prstrms"
 #define MY_FILEDESCRIPTION "PRSTRMS Library"
 
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
 #ifdef _DEBUG
 #define MY_DEBUG_STR " (debug)"
 #define MY_FILEFLAGS_1 VS_FF_DEBUG
 #else
 #define MY_DEBUG_STR ""
 #define MY_FILEFLAGS_1 0x0L
 #endif
 #if PR_BETA
@@ -61,17 +65,17 @@ BEGIN
     BLOCK "StringFileInfo"
     BEGIN
         BLOCK "040904B0" // Lang=US English, CharSet=Unicode
         BEGIN
             VALUE "CompanyName", "Netscape Communications Corporation\0"
             VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
             VALUE "FileVersion", PR_VERSION "\0"
             VALUE "InternalName", MY_INTERNAL_NAME "\0"
-            VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+            VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
             VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
             VALUE "ProductName", "Netscape Portable Runtime\0"
             VALUE "ProductVersion", PR_VERSION "\0"
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x409, 1200
index 04732ff75433c2e1ec45c85ef1dc9eee79235c01..fa75d4da838d1eb430448e405ea838791c68382a
GIT binary patch
literal 97889
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
--- a/makefile.win
+++ b/makefile.win
@@ -77,17 +77,17 @@ PR_OBJDIR = WIN954.0_OPT.OBJ
 # The rules.  Simply invoke gmake with the same target.
 # The default target is 'all'.  For Win16, set up the
 # environment to use the Watcom compiler, Watcom headers,
 # and Watcom libs.
 #
 
 all:: export libs install
 
-export libs install clobber clobber_all clean::
+export libs install clobber clobber_all clean depend::
 !if "$(MOZ_BITS)" == "16"
 	set PATH=%WATCPATH%
 	set INCLUDE=%WATC_INC%
 	set LIB=%WATC_LIB%
 !endif
 	$(GMAKE) $(GMAKE_FLAGS) $@
 !if "$(MOZ_BITS)" == "16"
 	set PATH=%MSVCPATH%
@@ -98,11 +98,8 @@ export libs install clobber clobber_all 
 !if "$(MOZ_BITS)" != "16"
 export::
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\include\*.h $(DIST)\include
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\include\obsolete\*.h $(DIST)\include\obsolete
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\include\private\*.h $(DIST)\include\private
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\lib\*.lib $(DIST)\lib
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\lib\*.dll $(DIST)\bin
 !endif
-
-depend::
-	@echo NSPR20 has no dependencies.  Skipped.
--- a/pr/include/MANIFEST
+++ b/pr/include/MANIFEST
@@ -32,16 +32,17 @@ prprf.h
 prproces.h
 prrng.h
 prrwlock.h
 prshm.h
 prshma.h
 prsystem.h
 prthread.h
 prtime.h
+prtpool.h
 prtrace.h
 prtypes.h
 prvrsion.h
 prwin16.h
 
 obsolete/protypes.h
 obsolete/prsem.h
 obsolete/probslet.h
--- a/pr/include/md/_aix.h
+++ b/pr/include/md/_aix.h
@@ -54,16 +54,17 @@
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ONLY_ST_ATIME
 #ifdef _PR_INET6
 #define _PR_HAVE_GETHOSTBYNAME2
 #endif
 #define _PR_HAVE_SYSV_SEMAPHORES
 #define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
 
 /* Timer operations */
 #if defined(AIX_TIMERS)
 extern PRIntervalTime _MD_AixGetInterval(void);
 #define _MD_GET_INTERVAL _MD_AixGetInterval
 
 extern PRIntervalTime _MD_AixIntervalPerSec(void);
 #define _MD_INTERVAL_PER_SEC _MD_AixIntervalPerSec
--- a/pr/include/md/_aix32.cfg
+++ b/pr/include/md/_aix32.cfg
@@ -68,16 +68,18 @@
 #define PR_ALIGN_OF_FLOAT   4
 #define PR_ALIGN_OF_DOUBLE  4
 #define PR_ALIGN_OF_POINTER 4
 
 #define	HAVE_LONG_LONG
 #undef	HAVE_ALIGNED_DOUBLES
 #undef	HAVE_ALIGNED_LONGLONGS
 
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
 #ifndef NO_NSPR_10_SUPPORT
 
 #define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
 #define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
 #define BYTES_PER_INT 		PR_BYTES_PER_INT
 #define BYTES_PER_INT64		PR_BYTES_PER_INT64
 #define BYTES_PER_LONG		PR_BYTES_PER_LONG
 #define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
--- a/pr/include/md/_aix32in6.cfg
+++ b/pr/include/md/_aix32in6.cfg
@@ -71,16 +71,17 @@
 
 #define	HAVE_LONG_LONG
 #undef	HAVE_ALIGNED_DOUBLES
 #undef	HAVE_ALIGNED_LONGLONGS
 
 #ifndef _PR_INET6
 #define _PR_INET6
 #endif
+#define PR_AF_INET6 24  /* same as AF_INET6 */
 
 #ifndef NO_NSPR_10_SUPPORT
 
 #define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
 #define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
 #define BYTES_PER_INT 		PR_BYTES_PER_INT
 #define BYTES_PER_INT64		PR_BYTES_PER_INT64
 #define BYTES_PER_LONG		PR_BYTES_PER_LONG
--- a/pr/include/md/_aix64.cfg
+++ b/pr/include/md/_aix64.cfg
@@ -72,16 +72,17 @@
 
 #define	HAVE_LONG_LONG
 #undef	HAVE_ALIGNED_DOUBLES
 #undef	HAVE_ALIGNED_LONGLONGS
 
 #ifndef _PR_INET6
 #define _PR_INET6
 #endif
+#define PR_AF_INET6 24  /* same as AF_INET6 */
 
 #ifndef NO_NSPR_10_SUPPORT
 
 #define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
 #define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
 #define BYTES_PER_INT 		PR_BYTES_PER_INT
 #define BYTES_PER_INT64		PR_BYTES_PER_INT64
 #define BYTES_PER_LONG		PR_BYTES_PER_LONG
--- a/pr/include/md/_beos.h
+++ b/pr/include/md/_beos.h
@@ -280,32 +280,34 @@ struct protoent* getprotobynumber(int nu
 #define _MD_INIT_IO()
 #define _MD_INIT_FILEDESC(fd)
 
 #define _MD_OPEN_DIR _MD_open_dir
 #define _MD_READ_DIR _MD_read_dir
 #define _MD_CLOSE_DIR _MD_close_dir
 #define _MD_MAKE_NONBLOCK _MD_make_nonblock
 #define _MD_OPEN _MD_open
+#define _MD_OPEN_FILE _MD_open
 #define _MD_CLOSE_FILE _MD_close_file
 #define _MD_READ _MD_read
 #define _MD_WRITE _MD_write
 #define _MD_WRITEV _MD_writev
 #define _MD_LSEEK _MD_lseek
 #define _MD_LSEEK64 _MD_lseek64
 #define _MD_FSYNC _MD_fsync
 #define _MD_DELETE _MD_delete
 #define _MD_GETFILEINFO _MD_getfileinfo
 #define _MD_GETFILEINFO64 _MD_getfileinfo64
 #define _MD_GETOPENFILEINFO _MD_getopenfileinfo
 #define _MD_GETOPENFILEINFO64 _MD_getopenfileinfo64
 #define _MD_RENAME _MD_rename
 #define _MD_ACCESS _MD_access
 #define _MD_STAT stat
 #define _MD_MKDIR _MD_mkdir
+#define _MD_MAKE_DIR _MD_mkdir
 #define _MD_RMDIR _MD_rmdir
 #define _MD_PR_POLL _MD_pr_poll
 
 /* Network I/O */
 
 #define _MD_CLOSE_SOCKET _MD_close_socket
 #define _MD_CONNECT _MD_connect
 #define _MD_ACCEPT _MD_accept
--- a/pr/include/md/_hpux.h
+++ b/pr/include/md/_hpux.h
@@ -43,16 +43,17 @@
 #ifndef HAVE_STRERROR
 #define HAVE_STRERROR
 #endif
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ONLY_ST_ATIME
 #define _PR_HAVE_POSIX_SEMAPHORES
 #define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
 
 #undef _PR_HAVE_ATOMIC_OPS
 
 #if !defined(_PR_PTHREADS)
 
 #include <syscall.h>
 #include <setjmp.h>
 
--- a/pr/include/md/_hpux32.cfg
+++ b/pr/include/md/_hpux32.cfg
@@ -25,16 +25,18 @@
 
 #ifndef HPUX
 #define HPUX
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 
+#define PR_AF_INET6 22  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   4
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   4
--- a/pr/include/md/_hpux64.cfg
+++ b/pr/include/md/_hpux64.cfg
@@ -26,16 +26,18 @@
 #ifndef HPUX
 #define HPUX
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 #define IS_64
 
+#define PR_AF_INET6 22  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   8
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   8
--- a/pr/include/md/_irix.h
+++ b/pr/include/md/_irix.h
@@ -55,16 +55,17 @@
 #define _PR_HAVE_ATOMIC_OPS
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ST_ATIM
 #define _PR_HAVE_OFF64_T
 #define HAVE_POINTER_LOCALTIME_R
 #define _PR_HAVE_POSIX_SEMAPHORES
 #define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
 
 /* Initialization entry points */
 NSPR_API(void) _MD_EarlyInit(void);
 #define _MD_EARLY_INIT _MD_EarlyInit
 
 NSPR_API(void) _MD_IrixInit(void);
 #define _MD_FINAL_INIT _MD_IrixInit
 
--- a/pr/include/md/_irix32.cfg
+++ b/pr/include/md/_irix32.cfg
@@ -29,16 +29,18 @@
 
 #ifndef IRIX
 #define IRIX
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   4
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   4
--- a/pr/include/md/_irix64.cfg
+++ b/pr/include/md/_irix64.cfg
@@ -30,16 +30,18 @@
 #ifndef IRIX
 #define IRIX
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 #define IS_64
 
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   8
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   8
--- a/pr/include/md/_linux.cfg
+++ b/pr/include/md/_linux.cfg
@@ -22,16 +22,18 @@
 #ifndef XP_UNIX
 #define XP_UNIX
 #endif
 
 #ifndef LINUX
 #define LINUX
 #endif
 
+#define PR_AF_INET6 10  /* same as AF_INET6 */
+
 #ifdef __powerpc__
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN    1
 
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
--- a/pr/include/md/_linux.h
+++ b/pr/include/md/_linux.h
@@ -65,16 +65,20 @@
 #endif
 #undef _PR_USE_POLL
 #define _PR_STAT_HAS_ONLY_ST_ATIME
 #if defined(__alpha)
 #define _PR_HAVE_LARGE_OFF_T
 #else
 #define _PR_NO_LARGE_FILES
 #endif
+#ifdef _PR_INET6
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_INET6_PROBE
+#endif
 #define _PR_HAVE_SYSV_SEMAPHORES
 #define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
 
 #ifdef _PR_PTHREADS
 
 extern void _MD_CleanupBeforeExit(void);
 #define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit
 
--- a/pr/include/md/_macos.h
+++ b/pr/include/md/_macos.h
@@ -313,16 +313,17 @@ typedef enum IOOperation {
     READ_ASYNC,
     WRITE_ASYNC
 } IOOperation;
 
 
 #define _MD_INIT_IO()
 
 #define _MD_OPEN 					_MD_Open
+#define _MD_OPEN_FILE 				_MD_Open
 #define _MD_CLOSE_FILE 				FSClose
 #define _MD_READ(fd,buf,amount) 	ReadWriteProc(fd,buf,amount,READ_ASYNC)
 #define _MD_WRITE(fd,buf,amount) 	ReadWriteProc(fd,buf,amount,WRITE_ASYNC)
 #define _MD_WRITE_SYNC(fd,buf,amount) WriteSyncProc(fd,buf,amount)
 #define _MD_GET_FILE_ERROR() 		_PR_MD_CURRENT_THREAD()->md.osErrCode
 #define _MD_LSEEK 					_MD_LSeek
 #define _MD_FSYNC 					_MD_FSync
 
@@ -363,16 +364,17 @@ extern PRStatus _MD_OpenDir(struct _MDDi
 #define	_MD_OPEN_DIR 		_MD_OpenDir
 
 extern char* _MD_ReadDir(struct _MDDir *md,PRIntn flags);
 #define	_MD_READ_DIR 		_MD_ReadDir
 
 #define	_MD_CLOSE_DIR 		_MD_CloseDir
 
 #define	_MD_MKDIR 			_MD_MkDir
+#define	_MD_MAKE_DIR		_MD_MkDir
 #define	_MD_RMDIR 			_MD_Delete
 
 /*
 ** Pipe I/O Related definitions (not implemented)
 */
 
 #define _MD_PIPEAVAILABLE(fd) -1
 
--- a/pr/include/md/_os2.h
+++ b/pr/include/md/_os2.h
@@ -177,32 +177,34 @@ struct _MDProcess {
 };
 
 /* --- Misc stuff --- */
 #define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
 
 /* --- IO stuff --- */
 
 #define _MD_OPEN                      (_PR_MD_OPEN)
+#define _MD_OPEN_FILE                 (_PR_MD_OPEN)
 #define _MD_READ                      (_PR_MD_READ)
 #define _MD_WRITE                     (_PR_MD_WRITE)
 #define _MD_WRITEV                    (_PR_MD_WRITEV)
 #define _MD_LSEEK                     (_PR_MD_LSEEK)
 #define _MD_LSEEK64                   (_PR_MD_LSEEK64)
 extern PRInt32 _MD_CloseFile(PRInt32 osfd);
 #define _MD_CLOSE_FILE                _MD_CloseFile
 #define _MD_GETFILEINFO               (_PR_MD_GETFILEINFO)
 #define _MD_GETFILEINFO64             (_PR_MD_GETFILEINFO64)
 #define _MD_GETOPENFILEINFO           (_PR_MD_GETOPENFILEINFO)
 #define _MD_GETOPENFILEINFO64         (_PR_MD_GETOPENFILEINFO64)
 #define _MD_STAT                      (_PR_MD_STAT)
 #define _MD_RENAME                    (_PR_MD_RENAME)
 #define _MD_ACCESS                    (_PR_MD_ACCESS)
 #define _MD_DELETE                    (_PR_MD_DELETE)
 #define _MD_MKDIR                     (_PR_MD_MKDIR)
+#define _MD_MAKE_DIR                  (_PR_MD_MKDIR)
 #define _MD_RMDIR                     (_PR_MD_RMDIR)
 #define _MD_LOCKFILE                  (_PR_MD_LOCKFILE)
 #define _MD_TLOCKFILE                 (_PR_MD_TLOCKFILE)
 #define _MD_UNLOCKFILE                (_PR_MD_UNLOCKFILE)
 
 /* --- Socket IO stuff --- */
 
 /* The ones that don't map directly may need to be re-visited... */
--- a/pr/include/md/_osf1.cfg
+++ b/pr/include/md/_osf1.cfg
@@ -31,16 +31,18 @@
 #undef  IS_BIG_ENDIAN
 #define	HAVE_LONG_LONG
 #define HAVE_ALIGNED_DOUBLES
 #define HAVE_ALIGNED_LONGLONGS
 #ifndef IS_64
 #define IS_64
 #endif
 
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   8
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   8
--- a/pr/include/md/_osf1.h
+++ b/pr/include/md/_osf1.h
@@ -41,19 +41,24 @@
 
 #define NEED_TIME_R
 #define USE_DLFCN
 
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ONLY_ST_ATIME
 #define _PR_HAVE_LARGE_OFF_T
-#ifdef _PR_INET6
 #define _PR_HAVE_GETIPNODEBYNAME
 #define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_INET6_PROBE
+#ifndef _PR_INET6
+#define AF_INET6 26
+#define AI_V4MAPPED 0x00000010
+#define AI_ALL      0x00000008
+#define AI_ADDRCONFIG 0x00000020
 #endif
 #define _PR_HAVE_POSIX_SEMAPHORES
 #define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
 
 #define USE_SETJMP
 
 #include <setjmp.h>
 
--- a/pr/include/md/_solaris.h
+++ b/pr/include/md/_solaris.h
@@ -68,16 +68,25 @@
 #endif
 
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ST_ATIM
 #define _PR_HAVE_POSIX_SEMAPHORES
 #define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
 #define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_INET6_PROBE
+#define _PR_ACCEPT_INHERIT_NONBLOCK
+#ifndef _PR_INET6
+#define AF_INET6 26
+#define AI_V4MAPPED 0x0001 
+#define AI_ALL      0x0002
+#define AI_ADDRCONFIG   0x0004
+#endif
 
 #include "prinrval.h"
 NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void);
 #define _MD_GET_INTERVAL                  _MD_Solaris_GetInterval
 NSPR_API(PRIntervalTime) _MD_Solaris_TicksPerSecond(void);
 #define _MD_INTERVAL_PER_SEC              _MD_Solaris_TicksPerSecond
 
 #if defined(_PR_HAVE_ATOMIC_OPS)
--- a/pr/include/md/_solaris32.cfg
+++ b/pr/include/md/_solaris32.cfg
@@ -36,16 +36,18 @@
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 #define PR_ALIGN_OF_INT64   4
 #define PR_ALIGN_OF_DOUBLE  4
 #else
 #error unknown processor
 #endif
 
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   4
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   4
--- a/pr/include/md/_solaris64.cfg
+++ b/pr/include/md/_solaris64.cfg
@@ -37,16 +37,18 @@
 #undef  IS_BIG_ENDIAN
 #define PR_ALIGN_OF_INT64   4
 #define PR_ALIGN_OF_DOUBLE  4
 #else
 #error unknown processor
 #endif
 #define IS_64
 
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   8
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   8
--- a/pr/include/md/_unixos.h
+++ b/pr/include/md/_unixos.h
@@ -329,29 +329,31 @@ extern PRInt32 	_PR_UnixSendFile(PRFileD
 
 extern PRStatus _MD_LockFile(PRInt32 osfd);
 extern PRStatus _MD_TLockFile(PRInt32 osfd);
 extern PRStatus _MD_UnlockFile(PRInt32 osfd);
 
 #define _MD_OPEN_DIR(dir, name)		    _MD_open_dir(dir, name)
 #define _MD_CLOSE_DIR(dir)		        _MD_close_dir(dir)
 #define _MD_READ_DIR(dir, flags)	    _MD_read_dir(dir, flags)
-#define _MD_OPEN(name, osflags, mode    )	_MD_open(name, osflags, mode)
+#define _MD_OPEN(name, osflags, mode)	_MD_open(name, osflags, mode)
+#define _MD_OPEN_FILE(name, osflags, mode)	_MD_open(name, osflags, mode)
 extern PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount);
 #define _MD_READ(fd,buf,amount)		    _MD_read(fd,buf,amount)
 extern PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount);
 #define _MD_WRITE(fd,buf,amount)	    _MD_write(fd,buf,amount)
 #define _MD_DELETE(name)		        _MD_delete(name)
 #define _MD_GETFILEINFO(fn, info)	    _MD_getfileinfo(fn, info)
 #define _MD_GETFILEINFO64(fn, info)	    _MD_getfileinfo64(fn, info)
 #define _MD_GETOPENFILEINFO(fd, info)	_MD_getopenfileinfo(fd, info)
 #define _MD_GETOPENFILEINFO64(fd, info)	_MD_getopenfileinfo64(fd, info)
 #define _MD_RENAME(from, to)		    _MD_rename(from, to)
 #define _MD_ACCESS(name, how)		    _MD_access(name, how)
 #define _MD_MKDIR(name, mode)		    _MD_mkdir(name, mode)
+#define _MD_MAKE_DIR(name, mode)		_MD_mkdir(name, mode)
 #define _MD_RMDIR(name)			        _MD_rmdir(name)
 #define _MD_ACCEPT_READ(sock, newSock, raddr, buf, amount)	_MD_accept_read(sock, newSock, raddr, buf, amount)
 
 #define _MD_LOCKFILE _MD_LockFile
 #define _MD_TLOCKFILE _MD_TLockFile
 #define _MD_UNLOCKFILE _MD_UnlockFile
 
 
--- a/pr/include/md/_unixware7.cfg
+++ b/pr/include/md/_unixware7.cfg
@@ -28,16 +28,18 @@
 #endif
 
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 #define HAVE_LONG_LONG
 #undef	HAVE_ALIGNED_DOUBLES
 #undef	HAVE_ALIGNED_LONGLONGS
 
+#define PR_AF_INET6 27  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   4
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   4
--- a/pr/include/md/_win95.cfg
+++ b/pr/include/md/_win95.cfg
@@ -26,16 +26,18 @@
 #ifndef WIN32
 #define WIN32
 #endif
 
 #ifndef WIN95
 #define WIN95
 #endif
 
+#define PR_AF_INET6 23  /* same as AF_INET6 */
+
 #if defined(_M_IX86) || defined(_X86_)
 
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
--- a/pr/include/md/_win95.h
+++ b/pr/include/md/_win95.h
@@ -153,35 +153,50 @@ struct _MDFileDesc {
 struct _MDProcess {
     HANDLE handle;
     DWORD id;
 };
 
 /* --- Misc stuff --- */
 #define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
 
+/* --- NT security stuff --- */
+
+extern void _PR_NT_InitSids(void);
+extern void _PR_NT_FreeSids(void);
+extern PRStatus _PR_NT_MakeSecurityDescriptorACL(
+    PRIntn mode,
+    DWORD accessTable[],
+    PSECURITY_DESCRIPTOR *resultSD,
+    PACL *resultACL
+);
+extern void _PR_NT_FreeSecurityDescriptorACL(
+    PSECURITY_DESCRIPTOR pSD, PACL pACL);
+
 /* --- IO stuff --- */
 
 #define _MD_OPEN                      _PR_MD_OPEN
+#define _MD_OPEN_FILE                 _PR_MD_OPEN_FILE
 #define _MD_READ                      _PR_MD_READ
 #define _MD_WRITE                     _PR_MD_WRITE
 #define _MD_WRITEV                    _PR_MD_WRITEV
 #define _MD_LSEEK                     _PR_MD_LSEEK
 #define _MD_LSEEK64                   _PR_MD_LSEEK64
 extern PRInt32 _MD_CloseFile(PRInt32 osfd);
 #define _MD_CLOSE_FILE                _MD_CloseFile
 #define _MD_GETFILEINFO               _PR_MD_GETFILEINFO
 #define _MD_GETFILEINFO64             _PR_MD_GETFILEINFO64
 #define _MD_GETOPENFILEINFO           _PR_MD_GETOPENFILEINFO
 #define _MD_GETOPENFILEINFO64         _PR_MD_GETOPENFILEINFO64
 #define _MD_STAT                      _PR_MD_STAT
 #define _MD_RENAME                    _PR_MD_RENAME     
 #define _MD_ACCESS                    _PR_MD_ACCESS     
 #define _MD_DELETE                    _PR_MD_DELETE     
 #define _MD_MKDIR                     _PR_MD_MKDIR      
+#define _MD_MAKE_DIR                  _PR_MD_MAKE_DIR
 #define _MD_RMDIR                     _PR_MD_RMDIR      
 #define _MD_LOCKFILE                  _PR_MD_LOCKFILE
 #define _MD_TLOCKFILE                 _PR_MD_TLOCKFILE
 #define _MD_UNLOCKFILE                _PR_MD_UNLOCKFILE
 
 /* --- Socket IO stuff --- */
 #define _MD_EACCES                WSAEACCES
 #define _MD_EADDRINUSE            WSAEADDRINUSE
--- a/pr/include/md/_winnt.cfg
+++ b/pr/include/md/_winnt.cfg
@@ -26,16 +26,18 @@
 #ifndef WIN32
 #define WIN32
 #endif
 
 #ifndef WINNT
 #define WINNT
 #endif
 
+#define PR_AF_INET6 23  /* same as AF_INET6 */
+
 #if defined(_M_IX86) || defined(_X86_)
 
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
--- a/pr/include/md/_winnt.h
+++ b/pr/include/md/_winnt.h
@@ -195,37 +195,52 @@ struct _MDProcess {
     HANDLE handle;
     DWORD id;
 };
 
 
 /* --- Misc stuff --- */
 #define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
 
+/* --- NT security stuff --- */
+
+extern void _PR_NT_InitSids(void);
+extern void _PR_NT_FreeSids(void);
+extern PRStatus _PR_NT_MakeSecurityDescriptorACL(
+    PRIntn mode,
+    DWORD accessTable[],
+    PSECURITY_DESCRIPTOR *resultSD,
+    PACL *resultACL
+);
+extern void _PR_NT_FreeSecurityDescriptorACL(
+    PSECURITY_DESCRIPTOR pSD, PACL pACL);
+
 /* --- IO stuff --- */
 
 extern PRInt32 _md_Associate(HANDLE);
 extern PRInt32 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket);
 
 #define _MD_OPEN                      _PR_MD_OPEN
+#define _MD_OPEN_FILE                 _PR_MD_OPEN_FILE
 #define _MD_READ                      _PR_MD_READ
 #define _MD_WRITE                     _PR_MD_WRITE
 #define _MD_WRITEV                    _PR_MD_WRITEV
 #define _MD_LSEEK                     _PR_MD_LSEEK
 #define _MD_LSEEK64                   _PR_MD_LSEEK64
 #define _MD_CLOSE_FILE(f)             _PR_MD_CLOSE(f, PR_FALSE)
 #define _MD_GETFILEINFO               _PR_MD_GETFILEINFO
 #define _MD_GETFILEINFO64             _PR_MD_GETFILEINFO64
 #define _MD_GETOPENFILEINFO           _PR_MD_GETOPENFILEINFO
 #define _MD_GETOPENFILEINFO64         _PR_MD_GETOPENFILEINFO64
 #define _MD_STAT                      _PR_MD_STAT
 #define _MD_RENAME                    _PR_MD_RENAME     
 #define _MD_ACCESS                    _PR_MD_ACCESS     
 #define _MD_DELETE                    _PR_MD_DELETE     
 #define _MD_MKDIR                     _PR_MD_MKDIR      
+#define _MD_MAKE_DIR                  _PR_MD_MAKE_DIR
 #define _MD_RMDIR                     _PR_MD_RMDIR      
 #define _MD_LOCKFILE                  _PR_MD_LOCKFILE
 #define _MD_TLOCKFILE                 _PR_MD_TLOCKFILE
 #define _MD_UNLOCKFILE                _PR_MD_UNLOCKFILE
 
 /* --- Socket IO stuff --- */
 #define _MD_GET_SOCKET_ERROR()    WSAGetLastError()
 #define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err)
--- a/pr/include/nspr.h
+++ b/pr/include/nspr.h
@@ -44,11 +44,13 @@
 #include "prproces.h"
 #include "prrng.h"
 #include "prrwlock.h"
 #include "prshm.h"
 #include "prshma.h"
 #include "prsystem.h"
 #include "prthread.h"
 #include "prtime.h"
+#include "prtpool.h"
+#include "prtrace.h"
 #include "prtypes.h"
 
 #endif /* nspr_h___ */
--- a/pr/include/obsolete/probslet.h
+++ b/pr/include/obsolete/probslet.h
@@ -29,27 +29,16 @@
 PR_BEGIN_EXTERN_C
 
 /*
 ** Yield the current thread.  The proper function to use in place of
 ** PR_Yield() is PR_Sleep() with an argument of PR_INTERVAL_NO_WAIT.
 */
 NSPR_API(PRStatus) PR_Yield(void);
 
-/*
-** These are obsolete and are replaced by PR_GetSocketOption() and
-** PR_SetSocketOption().
-*/
-
-NSPR_API(PRStatus) PR_GetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen);
-
-NSPR_API(PRStatus) PR_SetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen);
-
 /************************************************************************/
 /************* The following definitions are for select *****************/
 /************************************************************************/
 
 /*
 ** The following is obsolete and will be deleted in the next release!
 ** These are provided for compatibility, but are GUARANTEED to be slow.
 **
@@ -155,71 +144,13 @@ NSPR_API(PRInt32)     PR_FD_NISSET(PRInt
 #include <stat.h>
 #else
 #include <sys/stat.h>
 #endif
 
 NSPR_API(PRInt32) PR_Stat(const char *path, struct stat *buf);
 #endif /* NO_NSPR_10_SUPPORT */
 
-/***********************************************************************
-** FUNCTION: PR_CreateNetAddr(), PR_DestroyNetAddr()
-** DESCRIPTION:
-**  Create an instance of a PRNetAddr, assigning well known values as
-**  appropriate.
-**
-** INPUTS
-**  PRNetAddrValue val  The value to be assigned to the IP Address portion
-**                      of the network address. This can only specify the
-**                      special well known values that are equivalent to
-**                      INADDR_ANY and INADDR_LOOPBACK.
-**
-**  PRUInt16 port       The port number to be assigned in the structure.
-**
-** OUTPUTS:
-**  None
-**
-** RETURN:
-**  PRNetAddr *addr     The initialized address that has been allocated
-**                      from the heap. It must be freed by the caller.
-**                      A returned value of zero indicates an error. The
-**                      cause of the error (most likely low memory) may
-**                      be retrieved by calling PR_GetError().
-**
-***********************************************************************/
-NSPR_API(PRNetAddr*) PR_CreateNetAddr(PRNetAddrValue val, PRUint16 port);
-NSPR_API(PRStatus) PR_DestroyNetAddr(PRNetAddr *addr);
-
-
-
-/***********************************************************************
-** FUNCTION: PR_GetHostName() **OBSOLETE**
-**   Use PR_GetSystemInfo() (prsystem.h) with an argument of
-**   PR_SI_HOSTNAME instead.
-** DESCRIPTION:	
-** Get the DNS name of the hosting computer.
-**
-** INPUTS:
-**  char *name          The location where the host's name is stored.
-**  PRIntn bufsize      Number of bytes in 'name'.
-** OUTPUTS:
-**  PRHostEnt *name
-**                      This string is filled in by the runtime if the
-**                      function returns PR_SUCCESS. The string must be
-**                      allocated by the caller
-** RETURN:
-**  PRStatus            PR_SUCCESS if the  succeeds. If it fails the
-**                      result will be PR_FAILURE and the reason for
-**                      the failure can be retrieved by PR_GetError().
-***********************************************************************/
-NSPR_API(PRStatus) PR_GetHostName(char *name, PRUint32 namelen);
-
-/*
-** Return the current thread's last error string.
-** obsoleted by PR_GetErrorText().
-*/
-NSPR_API(const char *) PR_GetErrorString(void);
-
 PR_END_EXTERN_C
 
 #endif /* defined(PROBSLET_H) */
 
 /* probslet.h */
--- a/pr/include/prerr.h
+++ b/pr/include/prerr.h
@@ -215,18 +215,18 @@
 #define PR_END_OF_FILE_ERROR                     (-5938L)
 
 /* Seek error */
 #define PR_FILE_SEEK_ERROR                       (-5937L)
 
 /* The file is busy */
 #define PR_FILE_IS_BUSY_ERROR                    (-5936L)
 
-/* Reserved Error Code -5935 */
-#define PR_RESERVED_ERROR_5935                   (-5935L)
+/* The I/O operation was aborted */
+#define PR_OPERATION_ABORTED_ERROR               (-5935L)
 
 /* Operation is still in progress (probably a non-blocking connect) */
 #define PR_IN_PROGRESS_ERROR                     (-5934L)
 
 /* Operation has already been initiated (probably a non-blocking connect) */
 #define PR_ALREADY_INITIATED_ERROR               (-5933L)
 
 /* The wait group is empty */
--- a/pr/include/prinit.h
+++ b/pr/include/prinit.h
@@ -39,20 +39,19 @@ PR_BEGIN_EXTERN_C
 /*
 ** NSPR's version is used to determine the likelihood that the version you
 ** used to build your component is anywhere close to being compatible with
 ** what is in the underlying library.
 **
 ** The format of the version string is
 **     "<major version>.<minor version> <build date>"
 */
-#define PR_VERSION  "3.5"
-#define PR_VMAJOR   3
-#define PR_VMAJOR_STR "3"
-#define PR_VMINOR   5
+#define PR_VERSION  "4.0"
+#define PR_VMAJOR   4
+#define PR_VMINOR   0
 #define PR_VPATCH   0
 #define PR_BETA     PR_FALSE
 
 /*
 ** PRVersionCheck
 **
 ** The basic signature of the function that is called to provide version
 ** checking. The result will be a boolean that indicates the likelihood
--- a/pr/include/prio.h
+++ b/pr/include/prio.h
@@ -99,43 +99,55 @@ typedef enum PRTransmitFileFlags {
 #define PR_INADDR_ANY (unsigned long)0x00000000
 #define PR_INADDR_LOOPBACK 0x7f000001
 #define PR_INADDR_BROADCAST (unsigned long)0xffffffff
 
 #else /* WIN32 */
 
 #define PR_AF_INET AF_INET
 #define PR_AF_LOCAL AF_UNIX
-#ifdef AF_INET6
-#define PR_AF_INET6 AF_INET6
-#endif
 #define PR_INADDR_ANY INADDR_ANY
 #define PR_INADDR_LOOPBACK INADDR_LOOPBACK
 #define PR_INADDR_BROADCAST INADDR_BROADCAST
 
 #endif /* WIN32 */
 
 /*
+** Define PR_AF_INET6 in prcpucfg.h with the same
+** value as AF_INET6 on platforms with IPv6 support.
+** Otherwise define it here.
+*/
+#ifndef PR_AF_INET6
+#define PR_AF_INET6 100
+#endif
+
+/*
 **************************************************************************
 ** A network address
 **
 ** Only Internet Protocol (IPv4 and IPv6) addresses are supported.
 ** The address family must always represent IPv4 (AF_INET, probably == 2)
 ** or IPv6 (AF_INET6).
 **************************************************************************
 *************************************************************************/
-#if defined(_PR_INET6)
 
-#if !defined(AF_INET6)
-#error "AF_INET6 is not defined"
-#endif
+struct PRIPv6Addr {
+	union {
+		PRUint8  _S6_u8[16];
+		PRUint16 _S6_u16[8];
+		PRUint32 _S6_u32[4];
+		PRUint64 _S6_u64[2];
+	} _S6_un;
+};
+#define pr_s6_addr		_S6_un._S6_u8
+#define pr_s6_addr16	_S6_un._S6_u16
+#define pr_s6_addr32	_S6_un._S6_u32
+#define pr_s6_addr64 	_S6_un._S6_addr64
 
-typedef struct in6_addr PRIPv6Addr;
-
-#endif /* defined(_PR_INET6) */
+typedef struct PRIPv6Addr PRIPv6Addr;
 
 union PRNetAddr {
     struct {
         PRUint16 family;                /* address family (0x00ff maskable) */
 #ifdef XP_BEOS
         char data[10];                  /* Be has a smaller structure */
 #else
         char data[14];                  /* raw address data */
@@ -146,25 +158,23 @@ union PRNetAddr {
         PRUint16 port;                  /* port number */
         PRUint32 ip;                    /* The actual 32 bits of address */
 #ifdef XP_BEOS
         char pad[4];                    /* Be has a smaller structure */
 #else
         char pad[8];
 #endif
     } inet;
-#if defined(_PR_INET6)
     struct {
         PRUint16 family;                /* address family (AF_INET6) */
         PRUint16 port;                  /* port number */
         PRUint32 flowinfo;              /* routing information */
         PRIPv6Addr ip;                  /* the actual 128 bits of address */
         PRUint32 scope_id;              /* set of interfaces for a scope */
     } ipv6;
-#endif /* defined(_PR_INET6) */
 #if defined(XP_UNIX)
     struct {                            /* Unix domain socket address */
         PRUint16 family;                /* address family (AF_UNIX) */
         char path[104];                 /* null-terminated pathname */
     } local;
 #endif
 };
 
@@ -176,22 +186,27 @@ union PRNetAddr {
 
 #if defined(_PR_INET6)
 
 #define PR_NETADDR_SIZE(_addr) PR_NetAddrSize(_addr)
 
 #else
 
 #if defined(XP_UNIX)
-#define PR_NETADDR_SIZE(_addr) \
-        ((_addr)->raw.family == AF_UNIX \
-        ? sizeof((_addr)->local) \
-        : sizeof((_addr)->inet))
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : ((_addr)->raw.family == PR_AF_INET6	\
+        ? sizeof((_addr)->ipv6)					\
+        : sizeof((_addr)->local)))
 #else
-#define PR_NETADDR_SIZE(_addr) sizeof((_addr)->inet)
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : sizeof((_addr)->ipv6))
 #endif /* defined(XP_UNIX) */
 
 #endif /* defined(_PR_INET6) */
 
 /*
 ***************************************************************************
 ** PRSockOption
 **
@@ -346,20 +361,16 @@ typedef PRInt16 (PR_CALLBACK *PRPollFN)(
 typedef PRInt32 (PR_CALLBACK *PRAcceptreadFN)(
     PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
     void *buf, PRInt32 amount, PRIntervalTime t);
 typedef PRInt32 (PR_CALLBACK *PRTransmitfileFN)(
      PRFileDesc *sd, PRFileDesc *fd, const void *headers,
      PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime t);
 typedef PRStatus (PR_CALLBACK *PRGetsocknameFN)(PRFileDesc *fd, PRNetAddr *addr);
 typedef PRStatus (PR_CALLBACK *PRGetpeernameFN)(PRFileDesc *fd, PRNetAddr *addr);
-typedef PRStatus (PR_CALLBACK *PRGetsockoptFN)(  /* OBSOLETE */
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32 *optlen);
-typedef PRStatus (PR_CALLBACK *PRSetsockoptFN)(  /* OBSOLETE */
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen);
 typedef PRStatus (PR_CALLBACK *PRGetsocketoptionFN)(
     PRFileDesc *fd, PRSocketOptionData *data);
 typedef PRStatus (PR_CALLBACK *PRSetsocketoptionFN)(
     PRFileDesc *fd, const PRSocketOptionData *data);
 typedef PRInt32 (PR_CALLBACK *PRSendfileFN)(
 	PRFileDesc *networkSocket, PRSendFileData *sendData,
 	PRTransmitFileFlags flags, PRIntervalTime timeout);
 typedef PRIntn (PR_CALLBACK *PRReservedFN)(PRFileDesc *fd);
@@ -386,18 +397,18 @@ struct PRIOMethods {
     PRSendFN send;                  /* Send all the bytes specified             */
     PRRecvfromFN recvfrom;          /* Solicit (net) bytes and report source    */
     PRSendtoFN sendto;              /* Send bytes to (net) address specified    */
     PRPollFN poll;                  /* Test the fd to see if it is ready        */
     PRAcceptreadFN acceptread;      /* Accept and read on a new (net) fd        */
     PRTransmitfileFN transmitfile;  /* Transmit at entire file                  */
     PRGetsocknameFN getsockname;    /* Get (net) address associated with fd     */
     PRGetpeernameFN getpeername;    /* Get peer's (net) address                 */
-    PRGetsockoptFN getsockopt;      /*             OBSOLETE                     */
-    PRSetsockoptFN setsockopt;      /*             OBSOLETE                     */
+    PRReservedFN reserved_fn_6;     /* reserved for future use */
+    PRReservedFN reserved_fn_5;     /* reserved for future use */
     PRGetsocketoptionFN getsocketoption;
                                     /* Get current setting of specified option  */
     PRSetsocketoptionFN setsocketoption;
                                     /* Set value of specified option            */
     PRSendfileFN sendfile;			/* Send a (partial) file with header/trailer*/
     PRReservedFN reserved_fn_4;		/* reserved for future use */
     PRReservedFN reserved_fn_3;		/* reserved for future use */
     PRReservedFN reserved_fn_2;		/* reserved for future use */
@@ -569,45 +580,73 @@ NSPR_API(PRFileDesc*) PR_PopIOLayer(PRFi
  * RESTRICTIONS:
  * MEMORY:
  *     The return value, if not NULL, points to a dynamically allocated
  *     PRFileDesc object.
  * ALGORITHM:
  **************************************************************************
  */
 
-NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
 /* Open flags */
 #define PR_RDONLY       0x01
 #define PR_WRONLY       0x02
 #define PR_RDWR         0x04
 #define PR_CREATE_FILE  0x08
 #define PR_APPEND       0x10
 #define PR_TRUNCATE     0x20
 #define PR_SYNC         0x40
 #define PR_EXCL         0x80
 
 /*
 ** File modes ....
 **
-** CAVEAT: 'mode' is currently only applicable on UNIX platforms. We are
-** still in the process of seeing how these apply to other file systems.
+** CAVEAT: 'mode' is currently only applicable on UNIX platforms.
+** The 'mode' argument may be ignored by PR_Open on other platforms.
 **
 **   00400   Read by owner.
 **   00200   Write by owner.
 **   00100   Execute (search if a directory) by owner.
 **   00040   Read by group.
 **   00020   Write by group.
 **   00010   Execute by group.
 **   00004   Read by others.
 **   00002   Write by others
 **   00001   Execute by others.
 **
 */
 
+NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_OpenFile
+ * DESCRIPTION:
+ *     Open a file for reading, writing, or both.
+ *     PR_OpenFile has the same prototype as PR_Open but implements
+ *     the specified file mode where possible.
+ **************************************************************************
+ */
+
+/* File mode bits */
+#define PR_IRWXU 00700  /* read, write, execute/search by owner */
+#define PR_IRUSR 00400  /* read permission, owner */
+#define PR_IWUSR 00200  /* write permission, owner */
+#define PR_IXUSR 00100  /* execute/search permission, owner */
+#define PR_IRWXG 00070  /* read, write, execute/search by group */
+#define PR_IRGRP 00040  /* read permission, group */
+#define PR_IWGRP 00020  /* write permission, group */
+#define PR_IXGRP 00010  /* execute/search permission, group */
+#define PR_IRWXO 00007  /* read, write, execute/search by others */
+#define PR_IROTH 00004  /* read permission, others */
+#define PR_IWOTH 00002  /* write permission, others */
+#define PR_IXOTH 00001  /* execute/search permission, others */
+
+NSPR_API(PRFileDesc*) PR_OpenFile(
+    const char *name, PRIntn flags, PRIntn mode);
+
 /*
  **************************************************************************
  * FUNCTION: PR_Close
  * DESCRIPTION:
  *     Close a file or socket.
  * INPUTS:
  *     PRFileDesc *fd
  *         a pointer to a PRFileDesc.
@@ -1034,16 +1073,28 @@ NSPR_API(PRStatus) PR_CloseDir(PRDir *di
  *        trieved using PR_GetError().
  *************************************************************************
  */
 
 NSPR_API(PRStatus) PR_MkDir(const char *name, PRIntn mode);
 
 /*
  *************************************************************************
+ * FUNCTION: PR_MakeDir
+ * DESCRIPTION:
+ *     Create a new directory with the given name and access mode.
+ *     PR_MakeDir has the same prototype as PR_MkDir but implements
+ *     the specified access mode where possible.
+ *************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_MakeDir(const char *name, PRIntn mode);
+
+/*
+ *************************************************************************
  * FUNCTION: PR_RmDir
  * DESCRIPTION:
  *     Remove a directory by the given name.
  * INPUTS:
  *     const char *name
  *        The name of the directory to be removed. All the path components
  *        must already exist. Only the leaf component will be removed.
  * OUTPUTS:
@@ -1524,17 +1575,18 @@ NSPR_API(PRInt32) PR_SendFile(
 **
 ** INPUTS:
 **    PRFileDesc *listenSock
 **        A socket descriptor that has been called with the PR_Listen() 
 **        function, also known as the rendezvous socket.
 **    void *buf
 **        A pointer to a buffer to receive data sent by the client.  This 
 **        buffer must be large enough to receive <amount> bytes of data
-**        and two PRNetAddr structures, plus an extra 32 bytes.
+**        and two PRNetAddr structures, plus an extra 32 bytes. See:
+**        PR_ACCEPT_READ_BUF_OVERHEAD.
 **    PRInt32 amount
 **        The number of bytes of client data to receive.  Does not include
 **        the size of the PRNetAddr structures.  If 0, no data will be read
 **        from the client.
 **    PRIntervalTime timeout
 **        The timeout interval only applies to the read portion of the 
 **        operation.  PR_AcceptRead will block indefinitely until the 
 **        connection is accepted; the read will timeout after the timeout 
@@ -1547,17 +1599,26 @@ NSPR_API(PRInt32) PR_SendFile(
 **        The address of the remote socket.  This parameter will only be
 **        valid if the function return does not indicate failure.  The
 **        returned address is not guaranteed to be properly aligned.
 ** 
 ** RETURNS:
 **     The number of bytes read from the client or -1 on failure.  The reason 
 **     for the failure is obtained by calling PR_GetError().
 **************************************************************************
-**/
+**/       
+/* define buffer overhead constant. Add this value to the user's 
+** data length when allocating a buffer to accept data.
+**    Example:
+**    #define USER_DATA_SIZE 10
+**    char buf[USER_DATA_SIZE + PR_ACCEPT_READ_BUF_OVERHEAD];
+**    bytesRead = PR_AcceptRead( s, fd, &a, &p, USER_DATA_SIZE, ...);
+*/
+#define PR_ACCEPT_READ_BUF_OVERHEAD (32+(2*sizeof(PRNetAddr)))
+
 NSPR_API(PRInt32) PR_AcceptRead(
     PRFileDesc *listenSock, PRFileDesc **acceptedSock,
     PRNetAddr **peerAddr, void *buf, PRInt32 amount, PRIntervalTime timeout);
 
 /*
 *************************************************************************
 ** FUNCTION: PR_NewTCPSocketPair
 ** DESCRIPTION:
--- a/pr/include/pripcsem.h
+++ b/pr/include/pripcsem.h
@@ -33,16 +33,17 @@
  * Because POSIX named semaphores have kernel persistence,
  * we are forced to have a delete function in this API.
  */
 
 #ifndef pripcsem_h___
 #define pripcsem_h___
 
 #include "prtypes.h"
+#include "prio.h"
 
 PR_BEGIN_EXTERN_C
 
 /*
  * PRSem is an opaque structure that represents a named
  * semaphore.
  */
 typedef struct PRSem PRSem;
--- a/pr/include/private/pprio.h
+++ b/pr/include/private/pprio.h
@@ -203,28 +203,16 @@ NSPR_API(PRFileDesc*)	PR_NTFast_Accept(P
 **    so that the socket can make general purpose socket calls.
 **    Without calling this, the only operations supported on the socket
 **    Are PR_Read, PR_Write, PR_Transmitfile, and PR_Close.
 */
 NSPR_API(void) PR_NTFast_UpdateAcceptContext(PRFileDesc *acceptSock, 
                                         PRFileDesc *listenSock);
 
 
-/* FUNCTION: PR_NT_UseNonblock
-** DESCRIPTION:
-**    This function only works on NT.  It tells nspr to use nonblocking io
-**    rather than async IO.  There is no way to use some of each.  This 
-**    function should be called immediately after calling PR_Init().
-**
-**    WARNING: THIS FUNCTION IS A TEMPORARY HACK AND WILL BE REMOVED SHORTLY
-**    (LIKE ALL FUNCTIONS IN THE PRIVATE AREA).  DO NOT USE THIS FUNCTION AT
-**    ALL WITHOUT CONTACTING mbelshe@netscape.com.
-*/
-NSPR_API(void) PR_NT_UseNonblock();
-
 /* FUNCTION: PR_NT_CancelIo
 ** DESCRIPTION:
 **    Cancel IO operations on fd.
 */
 NSPR_API(PRStatus) PR_NT_CancelIo(PRFileDesc *fd);
 
 
 #endif /* WIN32 */
--- a/pr/include/private/primpl.h
+++ b/pr/include/private/primpl.h
@@ -181,21 +181,16 @@ struct _PT_Notified
 #define PT_THREAD_RESUMED   0x80    /* thread has been resumed */
 #define PT_THREAD_SETGCABLE 0x100   /* set the GCAble flag */
 
 #if defined(DEBUG)
 
 typedef struct PTDebug
 {
     PRTime timeStarted;
-    PRUintn predictionsFoiled;
-    PRUintn pollingListMax;
-    PRUintn continuationsServed;
-    PRUintn recyclesNeeded;
-    PRUintn quiescentIO;
     PRUintn locks_created, locks_destroyed;
     PRUintn locks_acquired, locks_released;
     PRUintn cvars_created, cvars_destroyed;
     PRUintn cvars_notified, delayed_cv_deletes;
 } PTDebug;
 
 NSPR_API(void) PT_GetStats(PTDebug* here);
 NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
@@ -1030,16 +1025,19 @@ extern void _PR_MD_FREE_FILEDESC(PRFileD
 
 extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
 #define    _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK
 
 /* File I/O related */
 extern PRInt32 _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode);
 #define    _PR_MD_OPEN _MD_OPEN
 
+extern PRInt32 _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode);
+#define    _PR_MD_OPEN_FILE _MD_OPEN_FILE
+
 extern PRInt32 _PR_MD_CLOSE_FILE(PRInt32 osfd);
 #define    _PR_MD_CLOSE_FILE _MD_CLOSE_FILE
 
 extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount);
 #define    _PR_MD_READ _MD_READ
 
 extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount);
 #define    _PR_MD_WRITE _MD_WRITE
@@ -1062,16 +1060,19 @@ extern PRInt32 _PR_MD_ACCESS(const char 
 #define _PR_MD_ACCESS _MD_ACCESS
 
 extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf);
 #define _PR_MD_STAT _MD_STAT
 
 extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode);
 #define _PR_MD_MKDIR _MD_MKDIR
 
+extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode);
+#define _PR_MD_MAKE_DIR _MD_MAKE_DIR
+
 extern PRInt32 _PR_MD_RMDIR(const char *name);
 #define _PR_MD_RMDIR _MD_RMDIR
 
 /* Socket I/O related */
 extern void _PR_MD_INIT_IO(void);
 #define    _PR_MD_INIT_IO _MD_INIT_IO
 
 extern PRInt32 _PR_MD_CLOSE_SOCKET(PRInt32 osfd);
@@ -1416,19 +1417,17 @@ struct PRThread {
     PRInt32 errorStringSize;        /* byte length of current error string | zero */
     PRErrorCode errorCode;          /* current NSPR error code | zero */
     PRInt32 osErrorCode;            /* mapping of errorCode | zero */
     char *errorString;              /* current error string | NULL */
 
 #if defined(_PR_PTHREADS)
     pthread_t id;                   /* pthread identifier for the thread */
     PRBool okToDelete;              /* ok to delete the PRThread struct? */
-    PRCondVar *io_cv;               /* a condition used to run i/o */
     PRCondVar *waiting;             /* where the thread is waiting | NULL */
-	PRIntn io_tq_index;             /* the io-queue index for this thread */
     void *sp;                       /* recorded sp for garbage collection */
     PRThread *next, *prev;          /* simple linked list of all threads */
     PRUint32 suspend;               /* used to store suspend and resume flags */
 #ifdef PT_NO_SIGTIMEDWAIT
     pthread_mutex_t suspendResumeMutex;
     pthread_cond_t suspendResumeCV;
 #endif
     PRUint32 interrupt_blocked;     /* interrupt blocked */
@@ -1544,46 +1543,18 @@ struct PRFileMap {
 
 struct PRFilePrivate {
     PRInt32 state;
     PRBool nonblocking;
     PRBool inheritable;
     PRFileDesc *next;
     PRIntn lockCount;
     _MDFileDesc md;
-#ifdef _PR_PTHREADS
-    PRIntn eventMask[1];   /* An array of _pt_tq_count bitmasks.
-                            * eventMask[i] is only accessed by
-                            * the i-th i/o continuation thread.
-                            * A 0 in a bitmask means the event
-                            * should be igored in the revents
-                            * bitmask returned by poll.
-                            *
-                            * poll's revents bitmask is a short,
-                            * but we need to declare eventMask
-                            * as an array of PRIntn's so that
-                            * each bitmask can be updated
-                            * individually without disturbing
-                            * adjacent memory.  Only the lower
-                            * 16 bits of each PRIntn are used. */
-#endif
-/* IMPORTANT: eventMask MUST BE THE LAST FIELD OF THIS STRUCTURE */
 };
 
-/*
- * The actual size of the PRFilePrivate structure,
- * including the eventMask array at the end
- */
-#ifdef _PR_PTHREADS
-extern PRIntn _pt_tq_count;
-#define PRFILEPRIVATE_SIZE (sizeof(PRFilePrivate) + (_pt_tq_count-1) * sizeof(PRIntn))
-#else
-#define PRFILEPRIVATE_SIZE sizeof(PRFilePrivate)
-#endif
-
 struct PRDir {
     PRDirEntry d;
     _MDDir md;
 };
 
 extern void _PR_InitSegs(void);
 extern void _PR_InitStacks(void);
 extern void _PR_InitTPD(void);
@@ -1669,20 +1640,16 @@ extern PRLogModuleInfo *_pr_linker_lm;
 extern PRLogModuleInfo *_pr_sched_lm;
 extern PRLogModuleInfo *_pr_thread_lm;
 extern PRLogModuleInfo *_pr_gc_lm;
 
 extern PRFileDesc *_pr_stdin;
 extern PRFileDesc *_pr_stdout;
 extern PRFileDesc *_pr_stderr;
 
-#if defined(_PR_INET6)
-extern PRBool _pr_ipv6_enabled;  /* defined in prnetdb.c */
-#endif
-
 /* Overriding malloc, free, etc. */
 #if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \
         && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \
         && !defined(PURIFY) \
         && !defined(RHAPSODY) \
         && !defined(NEXTSTEP) \
         && !defined(QNX) \
         && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS))
--- a/pr/include/prnetdb.h
+++ b/pr/include/prnetdb.h
@@ -112,23 +112,21 @@ NSPR_API(PRStatus) PR_GetHostByName(
 **                      the function returns PR_SUCCESS. This structure
 **                      is allocated by the caller.
 ** RETURN:
 **  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
 **                      the result will be PR_FAILURE and the reason
 **                      for the failure can be retrieved by PR_GetError().
 ***********************************************************************/
 
-/*
- * #define PR_AI_ALL        0x08
- * #define PR_AI_V4MAPPED   0x10
- * #define PR_AI_ADDRCONFIG 0x20
- * #define PR_AI_DEFAULT    (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG)
- */
-#define PR_AI_DEFAULT 0x30
+
+#define PR_AI_ALL        0x08
+#define PR_AI_V4MAPPED   0x10
+#define PR_AI_ADDRCONFIG 0x20
+#define PR_AI_DEFAULT    (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG)
 
 NSPR_API(PRStatus) PR_GetIPNodeByName(
     const char *hostname,
     PRUint16 af,
     PRIntn flags,
     char *buf,
     PRIntn bufsize,
     PRHostEnt *hostentry);
@@ -212,17 +210,18 @@ NSPR_API(PRIntn) PR_EnumerateHostEnt(
 **  PRStatus            To indicate success or failure. If the latter, the
 **                      reason for the failure can be retrieved by calling
 **                      PR_GetError();
 ***********************************************************************/
 typedef enum PRNetAddrValue
 {
     PR_IpAddrNull,      /* do NOT overwrite the IP address */
     PR_IpAddrAny,       /* assign logical INADDR_ANY to IP address */
-    PR_IpAddrLoopback   /* assign logical INADDR_LOOPBACK */
+    PR_IpAddrLoopback,  /* assign logical INADDR_LOOPBACK  */
+    PR_IpAddrV4Mapped   /* IPv4 mapped address */
 } PRNetAddrValue;
 
 NSPR_API(PRStatus) PR_InitializeNetAddr(
     PRNetAddrValue val, PRUint16 port, PRNetAddr *addr);
 
 /***********************************************************************
 ** FUNCTION: PR_SetNetAddr(), 
 ** DESCRIPTION:
@@ -262,16 +261,33 @@ NSPR_API(PRStatus) PR_SetNetAddr(
 **
 ** RETURN:
 **  PRBool                  PR_TRUE if the network address is of the
 **                          specified type, else PR_FALSE.
 ***********************************************************************/
 NSPR_API(PRBool) PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val);
 
 /***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_ConvertIPv4AddrToIPv6()
+** Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr
+**
+** INPUTS:
+**  PRUint32 	v4addr		IPv4 address
+**
+** OUTPUTS:
+**  PRIPv6Addr *v6addr      The converted IPv6 address
+**
+** RETURN:
+**  void
+**                       
+***********************************************************************/
+NSPR_API(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr);
+
+/***********************************************************************
 ** MACRO:	
 ** DESCRIPTION:	PR_NetAddrFamily()
 ** Get the 'family' field of a PRNetAddr union.
 **
 ** INPUTS:
 **  const PRNetAddr *addr   A network address.
 **
 ** RETURN:
@@ -285,22 +301,18 @@ NSPR_API(PRBool) PR_IsNetAddrType(const 
 ** Get the 'port' field of a PRNetAddr union.
 **
 ** INPUTS:
 **  const PRNetAddr *addr   A network address.
 **
 ** RETURN:
 **  PRUint16                The 'port' field of 'addr'.
 ***********************************************************************/
-#ifdef _PR_INET6
 #define PR_NetAddrInetPort(addr) \
     ((addr)->raw.family == PR_AF_INET6 ? (addr)->ipv6.port : (addr)->inet.port)
-#else
-#define PR_NetAddrInetPort(addr) ((addr)->inet.port)
-#endif
 
 /***********************************************************************
 ** FUNCTION:	
 ** DESCRIPTION:	PR_GetProtoByName()
 ** Lookup a protocol entry based on protocol's name
 **
 ** INPUTS:
 **  char *protocolname  Character string of the protocol's name.
@@ -353,38 +365,16 @@ NSPR_API(PRStatus) PR_GetProtoByName(
 **  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
 **                      the result will be PR_FAILURE and the reason
 **                      for the failure can be retrieved by PR_GetError().
 ***********************************************************************/
 NSPR_API(PRStatus) PR_GetProtoByNumber(
     PRInt32 protocolnumber, char* buffer, PRInt32 bufsize, PRProtoEnt* result);
 
 /***********************************************************************
-** FUNCTION:	
-** DESCRIPTION:	PR_SetIPv6Enable()
-**  Enable IPv6 capability on a platform that supports the architecture.
-**
-**  Note: IPv6 must first be enabled for the host platform. If it is not,
-**        the function will always return PR_FAILURE on any attempt to
-**        change the setting.
-**
-** INPUTS:
-**  PRBool itIs
-**                      Assign it a value of PR_TRUE to turn on IPv6
-**                      addressing, PR_FALSE to turn it off.
-** RETURN:
-**  PRStatus            PR_SUCCESS if the IPv6 is enabled for this particular
-**                      host. Otherwise it will return failure and GetError()
-**                      will confirm the result by indicating that the
-**                      protocol is not supported
-**                      (PR_PROTOCOL_NOT_SUPPORTED_ERROR) 
-***********************************************************************/
-NSPR_API(PRStatus) PR_SetIPv6Enable(PRBool itIs);
-
-/***********************************************************************
 ** FUNCTIONS: PR_ntohs, PR_ntohl, PR_ntohll, PR_htons, PR_htonl, PR_htonll
 **
 ** DESCRIPTION: API entries for the common byte ordering routines.
 **
 **      PR_ntohs        16 bit conversion from network to host
 **      PR_ntohl        32 bit conversion from network to host
 **      PR_ntohll       64 bit conversion from network to host
 **      PR_htons        16 bit conversion from host to network
@@ -394,19 +384,11 @@ NSPR_API(PRStatus) PR_SetIPv6Enable(PRBo
 ***********************************************************************/
 NSPR_API(PRUint16) PR_ntohs(PRUint16);
 NSPR_API(PRUint32) PR_ntohl(PRUint32);
 NSPR_API(PRUint64) PR_ntohll(PRUint64);
 NSPR_API(PRUint16) PR_htons(PRUint16);
 NSPR_API(PRUint32) PR_htonl(PRUint32);
 NSPR_API(PRUint64) PR_htonll(PRUint64);
 
-/***********************************************************************
-** FUNCTION: PR_FamilyInet
-**
-** DESCRIPTION: Routine to get value of address family for Internet Protocol
-**
-***********************************************************************/
-NSPR_API(PRUint16) PR_FamilyInet(void);
-
 PR_END_EXTERN_C
 
 #endif /* prnetdb_h___ */
--- a/pr/include/prrng.h
+++ b/pr/include/prrng.h
@@ -11,59 +11,20 @@
  * NPL.
  * 
  * The Initial Developer of this code under the NPL is Netscape
  * Communications Corporation.  Portions created by Netscape are
  * Copyright (C) 1999 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
-/*
-** Delete this section of the header after (if) agreement is reached to
-** provide the service suggested here. Move some parts of it, if
-** appropriate to platform specific implementation files.
-**
-** Proposal: Nothing in this header file should be construed as a
-** commitment on the part of the NSPR team, Netsacpe/AOL/Sun Alliance
-** et.al. to provide the API or function suggested in this header file.
-** This is a proposal, a draft, yadda. ... So, don't count on it.
-** lth. 29-Oct-1999
-**
-** --------------------------------------------------------------------
-**
-** Requirements, Discussion:
-**
-** Goal: foreach platform, find at least 160 bits of "good noise", that
-** is: from the platform itself, not extrapolated, stired, hashed,
-** xor'd, whatever, from a little available noise.
-**
-**
-** Required on the following platforms:
-**   MAC, Win9x, WinNT, Solaris, Linux (k: 2.2.x).
-** Best effort on: 
-**   AIX, HP-UX.
-** Not required on: 
-**   Tru65 Unix (Compaq)
-**
-** Notes: 
-** 
-** I presume it is legal to put this function on Mozilla.org,
-** that it is not regulated as "cryptographic 'munitions'". 
-**
-** Cartman says they need it 15-Jan-2000.
-**
-** --------------------------------------------------------------------
-*/
 
 /*
 ** prrng.h -- NSPR Random Number Generator
 ** 
-** 
-** 
-** 
 **
 ** lth. 29-Oct-1999.
 */
 
 #ifndef prrng_h___ 
 #define prrng_h___
 
 #include "prtypes.h"
@@ -108,18 +69,17 @@ PR_BEGIN_EXTERN_C
 **   Some platforms may block for up to a few seconds while they
 **   accumulate some noise. Busy machines generate lots of noise, but
 **   care is advised when using PR_GetRandomNoise() frequently in your
 **   application.
 **
 ** History:
 **   Parts of the model dependent implementation for PR_GetRandomNoise()
 **   were taken in whole or part from code previously in Netscape's NSS
-**   component. There is no Goddamned Goverenment Munitions is this
-**   code. Clinton: FOAD.
+**   component.
 **
 */
 NSPR_API(PRSize) PR_GetRandomNoise( 
     void    *buf,
     PRSize  size
 );
 
 PR_END_EXTERN_C
--- a/pr/include/prshm.h
+++ b/pr/include/prshm.h
@@ -108,16 +108,17 @@
 **
 ** lth. 18-Aug-1999.
 */
 
 #ifndef prshm_h___
 #define prshm_h___
 
 #include "prtypes.h"
+#include "prio.h"
 
 PR_BEGIN_EXTERN_C
 
 /*
 ** Declare opaque type PRSharedMemory.
 */
 typedef struct PRSharedMemory PRSharedMemory;
 
--- a/pr/include/prtpool.h
+++ b/pr/include/prtpool.h
@@ -17,70 +17,80 @@
  */
 
 #ifndef prtpool_h___
 #define prtpool_h___
 
 #include "prtypes.h"
 #include "prthread.h"
 #include "prio.h"
-#include "prerr.h"
 #include "prerror.h"
 
+/*
+ * NOTE:
+ *		THIS API IS A PRELIMINARY VERSION IN NSPR 4.0 AND IS SUBJECT TO
+ *		CHANGE
+ */
+
 PR_BEGIN_EXTERN_C
 
 typedef struct PRJobIoDesc {
     PRFileDesc *socket;
     PRErrorCode error;
     PRIntervalTime timeout;
 } PRJobIoDesc;
 
 typedef struct PRThreadPool PRThreadPool;
 typedef struct PRJob PRJob;
-typedef void (PR_CALLBACK *JobFn) (void *arg);
+typedef void (PR_CALLBACK *PRJobFn) (void *arg);
 
 /* Create thread pool */
-PR_EXTERN(PRThreadPool *)
+NSPR_API(PRThreadPool *)
 PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads,
-                          PRSize stacksize);
+                          PRUint32 stacksize);
 
 /* queue a job */
-PR_EXTERN(PRJob *)
-PR_QueueJob(PRThreadPool *tpool, JobFn fn, void *arg, PRBool joinable);
+NSPR_API(PRJob *)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable);
 
 /* queue a job, when a socket is readable */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
 PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod,
-							JobFn fn, void * arg, PRBool joinable);
+							PRJobFn fn, void * arg, PRBool joinable);
 
 /* queue a job, when a socket is writeable */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
 PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod,
-								JobFn fn, void * arg, PRBool joinable);
+								PRJobFn fn, void * arg, PRBool joinable);
 
 /* queue a job, when a socket has a pending connection */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
 PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod,
-									JobFn fn, void * arg, PRBool joinable);
+									PRJobFn fn, void * arg, PRBool joinable);
+
+/* queue a job, when the socket connection to addr succeeds or fails */
+NSPR_API(PRJob *)
+PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
+			const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable);
 
 /* queue a job, when a timer exipres */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
 PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
-								JobFn fn, void * arg, PRBool joinable);
+								PRJobFn fn, void * arg, PRBool joinable);
 /* cancel a job */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
 PR_CancelJob(PRJob *job);
 
 /* join a job */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
 PR_JoinJob(PRJob *job);
 
 /* shutdown pool */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
 PR_ShutdownThreadPool(PRThreadPool *tpool);
 
 /* join pool, wait for exit of all threads */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
 PR_JoinThreadPool(PRThreadPool *tpool);
 
 PR_END_EXTERN_C
 
 #endif /* prtpool_h___ */
--- a/pr/include/prtypes.h
+++ b/pr/include/prtypes.h
@@ -25,23 +25,16 @@
 **
 ** Since we do not wrap <stdlib.h> and all the other standard headers, authors
 ** of portable code will not know in general that they need these definitions.
 ** Instead of requiring these authors to find the dependent uses in their code
 ** and take the following steps only in those C files, we take steps once here
 ** for all C files.
 **/
 
-/* the following update, a big '#if 0' for most of this file
-** intentionally breaks the build of NSPR on the tip of the source tree
-** nobody but NSPR should be interested in the tip right now
-** anyway.
-*/
-#if 0
-
 #ifndef prtypes_h___
 #define prtypes_h___
 
 #ifdef MDCPUCFG
 #include MDCPUCFG
 #else
 #include "prcpucfg.h"
 #endif
@@ -479,9 +472,8 @@ typedef unsigned long PRUword;
 
 /********* ????????????? End Fix me ?????????????????????????????? *****/
 #endif /* NO_NSPR_10_SUPPORT */
 
 PR_END_EXTERN_C
 
 #endif /* prtypes_h___ */
 
-#endif /* the #if 0 that intentionally breaks the tree */
--- a/pr/include/prvrsion.h
+++ b/pr/include/prvrsion.h
@@ -69,19 +69,29 @@ typedef struct {
 /* on NT, restore the previous packing */
 #ifdef _WIN32
 #pragma pack(pop)
 #endif
 
 /*
  * All components must define an entrypoint named libVersionPoint which
  * is of type versionEntryPointType.
+ *
+ * For example, for a library named libfoo, we would have:
+ *
+ *   PRVersionDescription prVersionDescription_libfoo =
+ *   {
+ *       ...
+ *   };
+ *
+ *   PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
+ *   {
+ *       return &prVersionDescription_libfoo;
+ *   }
  */
-NSPR_API(const PRVersionDescription *) libVersionPoint(void);
-
 typedef const PRVersionDescription *(*versionEntryPointType)(void);
 
 /* 
  * Where you declare your libVersionPoint, do it like this: 
  * PR_IMPLEMENT(const PRVersionDescription *) libVersionPoint(void) {
  *  fill it in...
  * }
  */
--- a/pr/src/Makefile
+++ b/pr/src/Makefile
@@ -136,30 +136,31 @@ OS_LIBS		= -lsocket -lc
 endif
 
 ifeq ($(OS_ARCH),NEWS-OS)
 OS_LIBS		= -lsocket -lnsl -lgen -lresolv
 endif
 
 ifeq ($(OS_ARCH),WINNT)
 ifneq ($(OS_TARGET),WIN16)
-OS_LIBS		= wsock32.lib winmm.lib
+OS_LIBS		= advapi32.lib wsock32.lib winmm.lib
 endif
 endif
 
 #
 # Define platform-dependent OBJS
 #
 
 OBJS = \
     $(OBJDIR)/prvrsion.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prfdcach.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmwait.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmapopt.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/priometh.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prlayer.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prlog.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmmap.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prpolevt.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prprf.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prscanf.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prstdio.$(OBJ_SUFFIX) \
     threads/$(OBJDIR)/prcmon.$(OBJ_SUFFIX) \
@@ -222,20 +223,16 @@ OBJS += \
 	threads/combined/$(OBJDIR)/prucv.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prulock.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prustack.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/pruthr.$(OBJ_SUFFIX)
 endif
 
 endif
 
-ifeq ($(USE_IPV6), 1)
-OBJS += io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX)
-endif
-
 ifeq ($(USE_CPLUS), 1)
 OBJS += \
 	cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rccv.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcfileio.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcinrval.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcio.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rclock.$(OBJ_SUFFIX) \
@@ -284,30 +281,32 @@ else
 ifeq ($(OS_TARGET), WIN95)
 OBJS +=	md/windows/$(OBJDIR)/w95io.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w95sock.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w95thred.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w95cv.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntgc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntmisc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntinrval.$(OBJ_SUFFIX) \
+	md/windows/$(OBJDIR)/ntsec.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/ntsem.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/win32_errors.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w32ipcsem.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32poll.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32rng.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32shm.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w95dllmain.$(OBJ_SUFFIX)
 else
 OBJS +=	md/windows/$(OBJDIR)/ntdllmn.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntio.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntgc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntthread.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntmisc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntinrval.$(OBJ_SUFFIX) \
+	md/windows/$(OBJDIR)/ntsec.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/ntsem.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/win32_errors.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w32ipcsem.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w32rng.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32shm.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32poll.$(OBJ_SUFFIX)
 endif
 endif
--- a/pr/src/Makefile.in
+++ b/pr/src/Makefile.in
@@ -157,16 +157,17 @@ endif # USE_AUTOCONF
 #
 
 OBJS = \
     $(OBJDIR)/prvrsion.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prfdcach.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmwait.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmapopt.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/priometh.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prlayer.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prlog.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmmap.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prpolevt.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prprf.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prscanf.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prstdio.$(OBJ_SUFFIX) \
     threads/$(OBJDIR)/prcmon.$(OBJ_SUFFIX) \
@@ -224,20 +225,16 @@ OBJS += \
 	threads/combined/$(OBJDIR)/prucv.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prulock.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prustack.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/pruthr.$(OBJ_SUFFIX)
 endif
 
 endif
 
-ifeq ($(USE_IPV6), 1)
-OBJS += io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX)
-endif
-
 ifeq ($(USE_CPLUS), 1)
 OBJS += \
 	cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rccv.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcfileio.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcinrval.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcio.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rclock.$(OBJ_SUFFIX) \
--- a/pr/src/io/Makefile
+++ b/pr/src/io/Makefile
@@ -27,16 +27,17 @@ ifeq ($(OS_RELEASE),4.1.3_U1)
 OPTIMIZER =
 endif
 endif
 
 CSRCS = \
     prfdcach.c \
     prmwait.c \
     priometh.c \
+    pripv6.c \
 	prmapopt.c \
     prlayer.c \
     prlog.c \
 	prmmap.c \
     prpolevt.c \
 	prprf.c \
 	prscanf.c \
 	prstdio.c  \
@@ -46,20 +47,16 @@ ifndef USE_PTHREADS
     CSRCS += \
 	    prdir.c \
 	    prfile.c \
 	    prio.c \
 	    prsocket.c \
 	    $(NULL)
 endif
 
-ifdef USE_IPV6
-CSRCS += pripv6.c
-endif
-
 TARGETS	= $(OBJS)
 
 INCLUDES = -I$(DIST)/include -I$(MOD_DEPTH)/pr/include -I$(MOD_DEPTH)/pr/include/private
 
 DEFINES     += -D_NSPR_BUILD_
 
 include $(MOD_DEPTH)/config/rules.mk
 
--- a/pr/src/io/Makefile.in
+++ b/pr/src/io/Makefile.in
@@ -32,16 +32,17 @@ ifeq ($(OS_RELEASE),4.1.3_U1)
 OPTIMIZER =
 endif
 endif
 
 CSRCS = \
     prfdcach.c \
     prmwait.c \
     priometh.c \
+    pripv6.c \
 	prmapopt.c \
     prlayer.c \
     prlog.c \
 	prmmap.c \
     prpolevt.c \
 	prprf.c \
 	prscanf.c \
 	prstdio.c  \
@@ -51,20 +52,16 @@ ifndef USE_PTHREADS
     CSRCS += \
 	    prdir.c \
 	    prfile.c \
 	    prio.c \
 	    prsocket.c \
 	    $(NULL)
 endif
 
-ifdef USE_IPV6
-CSRCS += pripv6.c
-endif
-
 TARGETS	= $(OBJS)
 
 INCLUDES = -I$(DIST)/include -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
 
 DEFINES	+= -D_NSPR_BUILD_
 
 include $(topsrcdir)/config/rules.mk
 
--- a/pr/src/io/prdir.c
+++ b/pr/src/io/prdir.c
@@ -65,16 +65,28 @@ PRInt32 rv;
 
 	rv = _PR_MD_MKDIR(name, mode);
 	if (rv < 0) {
 		return PR_FAILURE;
 	} else
 		return PR_SUCCESS;
 }
 
+PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode)
+{
+PRInt32 rv;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+	rv = _PR_MD_MAKE_DIR(name, mode);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
 PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name)
 {
 PRInt32 rv;
 
 	rv = _PR_MD_RMDIR(name);
 	if (rv < 0) {
 		return PR_FAILURE;
 	} else
--- a/pr/src/io/prfdcach.c
+++ b/pr/src/io/prfdcach.c
@@ -110,24 +110,24 @@ PRFileDesc *_PR_Getfd()
 
         } while (NULL == fd);  /* then go around and allocate a new one */
     }
 
 finished:
     fd->dtor = NULL;
     fd->lower = fd->higher = NULL;
     fd->identity = PR_NSPR_IO_LAYER;
-    memset(fd->secret, 0, PRFILEPRIVATE_SIZE);
+    memset(fd->secret, 0, sizeof(PRFilePrivate));
     return fd;
 
 allocate:
     fd = PR_NEW(PRFileDesc);
     if (NULL != fd)
     {
-        fd->secret = (PRFilePrivate *) PR_MALLOC(PRFILEPRIVATE_SIZE);
+        fd->secret = PR_NEW(PRFilePrivate);
         if (NULL == fd->secret) PR_DELETE(fd);
     }
     if (NULL != fd) goto finished;
     else return NULL;
 
 }  /* _PR_Getfd */
 
 /*
--- a/pr/src/io/prfile.c
+++ b/pr/src/io/prfile.c
@@ -263,18 +263,18 @@ static PRIOMethods _pr_fileMethods = {
     (PRSendFN)_PR_InvalidInt,		
     (PRRecvfromFN)_PR_InvalidInt,	
     (PRSendtoFN)_PR_InvalidInt,		
     FilePoll,         
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,	
     (PRGetpeernameFN)_PR_InvalidStatus,	
-    (PRGetsockoptFN)_PR_InvalidStatus,	
-    (PRSetsockoptFN)_PR_InvalidStatus,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRReservedFN)_PR_InvalidInt,	
     (PRGetsocketoptionFN)_PR_InvalidStatus,	
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -307,18 +307,18 @@ static PRIOMethods _pr_pipeMethods = {
     (PRSendFN)_PR_InvalidInt,		
     (PRRecvfromFN)_PR_InvalidInt,	
     (PRSendtoFN)_PR_InvalidInt,		
     FilePoll,         
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,	
     (PRGetpeernameFN)_PR_InvalidStatus,	
-    (PRGetsockoptFN)_PR_InvalidStatus,	
-    (PRSetsockoptFN)_PR_InvalidStatus,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRReservedFN)_PR_InvalidInt,	
     (PRGetsocketoptionFN)_PR_InvalidStatus,	
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -343,16 +343,36 @@ PR_IMPLEMENT(PRFileDesc*) PR_Open(const 
         fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
         if (!fd) {
             (void) _PR_MD_CLOSE_FILE(osfd);
         }
     }
     return fd;
 }
 
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
+    const char *name, PRIntn flags, PRIntn mode)
+{
+    PRInt32 osfd;
+    PRFileDesc *fd = 0;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    /* Map pr open flags and mode to os specific flags */
+
+    osfd = _PR_MD_OPEN_FILE(name, flags, mode);
+    if (osfd != -1) {
+        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+        if (!fd) {
+            (void) _PR_MD_CLOSE_FILE(osfd);
+        }
+    }
+    return fd;
+}
+
 PRInt32 PR_GetSysfdTableMax(void)
 {
 #if defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX)
     struct rlimit rlim;
 
     if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
        /* XXX need to call PR_SetError() */
        return -1;
--- a/pr/src/io/priometh.c
+++ b/pr/src/io/priometh.c
@@ -43,18 +43,18 @@ PRIOMethods _pr_faulty_methods = {
     (PRSendFN)_PR_InvalidInt,        
     (PRRecvfromFN)_PR_InvalidInt,    
     (PRSendtoFN)_PR_InvalidInt,        
     (PRPollFN)_PR_InvalidInt16,
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,    
     (PRGetpeernameFN)_PR_InvalidStatus,    
-    (PRGetsockoptFN)_PR_InvalidStatus,    
-    (PRSetsockoptFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
     (PRGetsocketoptionFN)_PR_InvalidStatus,
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt
@@ -242,36 +242,16 @@ PR_IMPLEMENT(PRStatus) PR_GetSockName(PR
 	return((fd->methods->getsockname)(fd,addr));
 }
 
 PR_IMPLEMENT(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
 {
 	return((fd->methods->getpeername)(fd,addr));
 }
 
-PR_IMPLEMENT(PRStatus) PR_GetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
-#if defined(DEBUG)
-    static PRBool warn = PR_TRUE;
-    if (warn) warn = _PR_Obsolete("PR_GetSockOpt()", "PR_GetSocketOption()");
-#endif
-	return((fd->methods->getsockopt)(fd, optname, optval, optlen));
-}
-
-PR_IMPLEMENT(PRStatus) PR_SetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
-#if defined(DEBUG)
-    static PRBool warn = PR_TRUE;
-    if (warn) warn = _PR_Obsolete("PR_SetSockOpt()", "PR_SetSocketOption()");
-#endif
-	return((fd->methods->setsockopt)(fd, optname, optval, optlen));
-}
-
 PR_IMPLEMENT(PRStatus) PR_GetSocketOption(
     PRFileDesc *fd, PRSocketOptionData *data)
 {
 	return((fd->methods->getsocketoption)(fd, data));
 }
 
 PR_IMPLEMENT(PRStatus) PR_SetSocketOption(
     PRFileDesc *fd, const PRSocketOptionData *data)
--- a/pr/src/io/pripv6.c
+++ b/pr/src/io/pripv6.c
@@ -15,12 +15,346 @@
  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
 /*
 ** File:        pripv6.c
 ** Description: Support for various functions unique to IPv6
 */
+#include "primpl.h"
+#include <string.h>
 
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+
+static PRIOMethods ipv6_to_v4_tcpMethods;
+static PRIOMethods ipv6_to_v4_udpMethods;
+static PRDescIdentity _pr_ipv6_to_ipv4_id;
+extern PRBool IsValidNetAddr(const PRNetAddr *addr);
+extern PRIPv6Addr _pr_in6addr_any;
+extern PRIPv6Addr _pr_in6addr_loopback;
+
+/*
+ * convert an IPv4-mapped IPv6 addr to an IPv4 addr
+ */
+static void _PR_ConvertToIpv4NetAddr(const PRNetAddr *src_v6addr,
+											PRNetAddr *dst_v4addr)
+{
+const PRUint8 *srcp;
+
+	PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family);
+
+	if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) {
+		srcp = src_v6addr->ipv6.ip.pr_s6_addr;
+		memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4);
+    } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrAny)) {
+        dst_v4addr->inet.ip = htonl(INADDR_ANY);
+    } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrLoopback)) {
+        dst_v4addr->inet.ip = htonl(INADDR_LOOPBACK);
+    }
+	dst_v4addr->inet.family = PR_AF_INET;
+	dst_v4addr->inet.port = src_v6addr->ipv6.port;
+}
+
+/*
+ * convert an IPv4 addr to an IPv4-mapped IPv6 addr
+ */
+static void _PR_ConvertToIpv6NetAddr(const PRNetAddr *src_v4addr,
+                                            PRNetAddr *dst_v6addr)
+{
+PRUint8 *dstp;
+
+	PR_ASSERT(PR_AF_INET == src_v4addr->inet.family);
+	dst_v6addr->ipv6.family = PR_AF_INET6;
+	dst_v6addr->ipv6.port = src_v4addr->inet.port;
+
+ 	if (htonl(INADDR_ANY) == src_v4addr->inet.ip) {
+		dst_v6addr->ipv6.ip = _pr_in6addr_any;
+	} else {
+		dstp = dst_v6addr->ipv6.ip.pr_s6_addr;
+		memset(dstp, 0, 10);
+		memset(dstp + 10, 0xff, 2);
+		memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4);
+	}
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketBind(PRFileDesc *fd,
+								const PRNetAddr *addr)
+{
+	PRNetAddr tmp_ipv4addr;
+	const PRNetAddr *tmp_addrp;
+	PRFileDesc *lo = fd->lower;
+
+	if (PR_AF_INET6 != addr->raw.family) {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return PR_FAILURE;
+	}
+	if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+    			PR_IsNetAddrType(addr, PR_IpAddrAny)) {
+		_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+		tmp_addrp = &tmp_ipv4addr;
+	} else {
+        PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+		return PR_FAILURE;
+	}
+	return((lo->methods->bind)(lo,tmp_addrp));
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketConnect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRNetAddr tmp_ipv4addr;
+	const PRNetAddr *tmp_addrp;
+
+	if (PR_AF_INET6 != addr->raw.family) {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return PR_FAILURE;
+	}
+	if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+			PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
+		_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+		tmp_addrp = &tmp_ipv4addr;
+	} else {
+        PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+		return PR_FAILURE;
+	}
+	return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout);
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketSendTo(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRNetAddr tmp_ipv4addr;
+	const PRNetAddr *tmp_addrp;
+
+	if (PR_AF_INET6 != addr->raw.family) {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return PR_FAILURE;
+	}
+	if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+			PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
+		_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+		tmp_addrp = &tmp_ipv4addr;
+	} else {
+        PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+		return PR_FAILURE;
+	}
+    return (fd->lower->methods->sendto)(
+        fd->lower, buf, amount, flags, tmp_addrp, timeout);
+}
+
+static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept (
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRStatus rv;
+    PRFileDesc *newfd;
+    PRFileDesc *newstack;
+	PRNetAddr tmp_ipv4addr;
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    newstack = PR_NEW(PRFileDesc);
+    if (NULL == newstack)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    *newstack = *fd;  /* make a copy of the accepting layer */
+
+    newfd = (fd->lower->methods->accept)(fd->lower, &tmp_ipv4addr, timeout);
+    if (NULL == newfd)
+    {
+        PR_DELETE(newstack);
+        return NULL;
+    }
+	_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, addr);
+
+    rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return newfd;  /* that's it */
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd,
+			PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount,
+							PRIntervalTime timeout)
+{
+    PRInt32 nbytes;
+    PRStatus rv;
+	PRNetAddr tmp_ipv4addr;
+    PRFileDesc *newstack;
+
+    PR_ASSERT(sd != NULL);
+    PR_ASSERT(sd->lower != NULL);
 
-/* pripv6.c */
+    newstack = PR_NEW(PRFileDesc);
+    if (NULL == newstack)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+    *newstack = *sd;  /* make a copy of the accepting layer */
+
+    nbytes = sd->lower->methods->acceptread(
+        sd->lower, nd, ipv6_raddr, buf, amount, timeout);
+    if (-1 == nbytes)
+    {
+        PR_DELETE(newstack);
+        return nbytes;
+    }
+	tmp_ipv4addr = **ipv6_raddr;	/* copy */
+	_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr);
+
+    /* this PR_PushIOLayer call cannot fail */
+    rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return nbytes;
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetName(PRFileDesc *fd,
+										PRNetAddr *ipv6addr)
+{
+	PRStatus result;
+	PRNetAddr tmp_ipv4addr;
+
+	result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr);
+	if (PR_SUCCESS == result) {
+		_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+		PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+	}
+	return result;
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetPeerName(PRFileDesc *fd,
+										PRNetAddr *ipv6addr)
+{
+	PRStatus result;
+	PRNetAddr tmp_ipv4addr;
+
+	result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr);
+	if (PR_SUCCESS == result) {
+		_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+		PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+	}
+	return result;
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketRecvFrom(PRFileDesc *fd, void *buf,
+			PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr,
+				PRIntervalTime timeout)
+{
+	PRNetAddr tmp_ipv4addr;
+	PRInt32 result;
+
+    result = (fd->lower->methods->recvfrom)(
+        fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout);
+	if (-1 != result) {
+		_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+		PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+	}
+	return result;
+}
+
+#if defined(_PR_INET6_PROBE)
+PRBool _pr_ipv6_is_present;
+PR_EXTERN(PRBool) _pr_test_ipv6_socket();
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+void *_pr_getipnodebyname_fp;
+void *_pr_getipnodebyaddr_fp;
+void *_pr_freehostent_fp;
+#endif
+#endif
+
+PRStatus _pr_init_ipv6()
+{
+    const PRIOMethods *stubMethods;
+
+#if defined(_PR_INET6_PROBE)
 
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+	PRLibrary *lib;	
+	_pr_getipnodebyname_fp = PR_FindSymbolAndLibrary("getipnodebyname", &lib);
+	if (NULL != _pr_getipnodebyname_fp) {
+		_pr_freehostent_fp = PR_FindSymbol(lib, "freehostent");
+		if (NULL != _pr_freehostent_fp) {
+			_pr_getipnodebyaddr_fp = PR_FindSymbol(lib, "getipnodebyaddr");
+			if (NULL != _pr_getipnodebyaddr_fp)
+				_pr_ipv6_is_present = PR_TRUE;
+			else
+				_pr_ipv6_is_present = PR_FALSE;
+		} else
+			_pr_ipv6_is_present = PR_FALSE;
+		(void)PR_UnloadLibrary(lib);
+	} else
+		_pr_ipv6_is_present = PR_FALSE;
+	if (PR_TRUE == _pr_ipv6_is_present)
+#endif
+	
+	_pr_ipv6_is_present = _pr_test_ipv6_socket();
+	if (PR_TRUE == _pr_ipv6_is_present)
+			return PR_SUCCESS;
+#endif
+
+    _pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer");
+    PR_ASSERT(PR_INVALID_IO_LAYER != _pr_ipv6_to_ipv4_id);
+
+	stubMethods = PR_GetDefaultIOMethods();
+
+	ipv6_to_v4_tcpMethods = *stubMethods;  /* first get the entire batch */
+	/* then override the ones we care about */
+	ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect;
+	ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind;
+	ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept;
+	ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead;
+	ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
+	ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
+/*
+	ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
+	ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
+*/
+	ipv6_to_v4_udpMethods = *stubMethods;  /* first get the entire batch */
+	/* then override the ones we care about */
+	ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect;
+	ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind;
+	ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo;
+	ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom;
+	ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
+	ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
+/*
+	ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
+	ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
+*/
+	return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd)
+{
+	PRFileDesc *ipv6_fd = NULL;
+
+	/*
+	 * For platforms with no support for IPv6 
+	 * create layered socket for IPv4-mapped IPv6 addresses
+	 */
+	if (fd->methods->file_type == PR_DESC_SOCKET_TCP)
+		ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
+									&ipv6_to_v4_tcpMethods);
+	else
+		ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
+									&ipv6_to_v4_udpMethods);
+	if (NULL == ipv6_fd) {
+		goto errorExit;
+	} 
+	ipv6_fd->secret = NULL;
+
+	if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) {
+		goto errorExit;
+	}
+
+	return PR_SUCCESS;
+errorExit:
+
+	if (ipv6_fd)
+		ipv6_fd->dtor(ipv6_fd);
+	return PR_FAILURE;
+}
+
+#endif /* !defined(_PR_INET6) || defined(_PR_INET6_PROBE) */
--- a/pr/src/io/prlayer.c
+++ b/pr/src/io/prlayer.c
@@ -314,34 +314,16 @@ static PRStatus PR_CALLBACK pl_DefGetsoc
 static PRStatus PR_CALLBACK pl_DefGetpeername (PRFileDesc *fd, PRNetAddr *addr)
 {
     PR_ASSERT(fd != NULL);
     PR_ASSERT(fd->lower != NULL);
 
     return (fd->lower->methods->getpeername)(fd->lower, addr);
 }
 
-static PRStatus PR_CALLBACK pl_DefGetsockopt (
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
-    PR_ASSERT(fd != NULL);
-    PR_ASSERT(fd->lower != NULL);
-
-    return (fd->lower->methods->getsockopt)(fd->lower, optname, optval, optlen);
-}
-
-static PRStatus PR_CALLBACK pl_DefSetsockopt (
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
-    PR_ASSERT(fd != NULL);
-    PR_ASSERT(fd->lower != NULL);
-
-    return (fd->lower->methods->setsockopt)(fd->lower, optname, optval, optlen);
-}
-
 static PRStatus PR_CALLBACK pl_DefGetsocketoption (
     PRFileDesc *fd, PRSocketOptionData *data)
 {
     PR_ASSERT(fd != NULL);
     PR_ASSERT(fd->lower != NULL);
 
     return (fd->lower->methods->getsocketoption)(fd->lower, data);
 }
@@ -389,18 +371,18 @@ static PRIOMethods pl_methods = {
     pl_DefSend,
     pl_DefRecvfrom,
     pl_DefSendto,
     pl_DefPoll,
     pl_DefAcceptread,
     pl_DefTransmitfile,
     pl_DefGetsockname,
     pl_DefGetpeername,
-    pl_DefGetsockopt,
-    pl_DefSetsockopt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
     pl_DefGetsocketoption,
     pl_DefSetsocketoption,
     pl_DefSendfile,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt
--- a/pr/src/io/prpolevt.c
+++ b/pr/src/io/prpolevt.c
@@ -164,18 +164,18 @@ static PRIOMethods _pr_polevt_methods = 
     (PRSendFN)_PR_InvalidInt,        
     (PRRecvfromFN)_PR_InvalidInt,    
     (PRSendtoFN)_PR_InvalidInt,        
     _pr_PolEvtPoll,
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,    
     (PRGetpeernameFN)_PR_InvalidStatus,    
-    (PRGetsockoptFN)_PR_InvalidStatus,    
-    (PRSetsockoptFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
     (PRGetsocketoptionFN)_PR_InvalidStatus,
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
--- a/pr/src/io/prsocket.c
+++ b/pr/src/io/prsocket.c
@@ -20,26 +20,24 @@
 
 #include <string.h>
 
 /************************************************************************/
 
 /* These two functions are only used in assertions. */
 #if defined(DEBUG)
 
-static PRBool IsValidNetAddr(const PRNetAddr *addr)
+PRBool IsValidNetAddr(const PRNetAddr *addr)
 {
     if ((addr != NULL)
 #ifdef XP_UNIX
-	    && (addr->raw.family != AF_UNIX)
+	    && (addr->raw.family != PR_AF_LOCAL)
 #endif
-#ifdef _PR_INET6
-	    && (addr->raw.family != AF_INET6)
-#endif
-	    && (addr->raw.family != AF_INET)) {
+	    && (addr->raw.family != PR_AF_INET6)
+	    && (addr->raw.family != PR_AF_INET)) {
         return PR_FALSE;
     }
     return PR_TRUE;
 }
 
 static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
 {
     /*
@@ -223,25 +221,36 @@ PR_IMPLEMENT(PRStatus) PR_DestroySocketP
     _PR_Putfd(fd);
     return PR_SUCCESS;
 }  /* PR_DestroySocketPollFd */
 
 static PRStatus PR_CALLBACK SocketConnect(
     PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
 {
 	PRInt32 rv;    /* Return value of _PR_MD_CONNECT */
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+	PRNetAddr addrCopy;
+#endif
 	PRThread *me = _PR_MD_CURRENT_THREAD();
 
 	if (_PR_PENDING_INTERRUPT(me)) {
 		me->flags &= ~_PR_INTERRUPT;
 		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
 		return PR_FAILURE;
 	}
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+	}
+#endif
 
-	rv = _PR_MD_CONNECT(fd, addr, PR_NETADDR_SIZE(addr), timeout);
+	rv = _PR_MD_CONNECT(fd, addrp, PR_NETADDR_SIZE(addr), timeout);
 	PR_LOG(_pr_io_lm, PR_LOG_MAX, ("connect -> %d", rv));
 	if (rv == 0)
 		return PR_SUCCESS;
 	else
 		return PR_FAILURE;
 }
 
 PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
@@ -409,16 +418,20 @@ PRIntervalTime timeout)
 	 * (which maps to _MD_makenonblock, see macsockotpt.c)
 	 * installs the async notifier routine needed to make blocking
 	 * I/O work properly.
 	 */
 #if !defined(SOLARIS) && !defined(IRIX) && !defined(WINNT)
 	_PR_MD_MAKE_NONBLOCK(fd2);
 #endif
 
+#ifdef _PR_INET6
+	if (addr && (AF_INET6 == addr->raw.family))
+        addr->raw.family = PR_AF_INET6;
+#endif
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
 	PR_ASSERT(IsValidNetAddrLen(addr, al) == PR_TRUE);
 
 	return fd2;
 }
 
 #ifdef WINNT
 PR_IMPLEMENT(PRFileDesc*) PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr,
@@ -453,39 +466,54 @@ PRIntervalTime timeout)
 	if (!fd2) {
 		_PR_MD_CLOSE_SOCKET(osfd);
 	} else {
 		fd2->secret->nonblocking = fd->secret->nonblocking;
 		fd2->secret->md.io_model_committed = PR_TRUE;
 	        PR_ASSERT(al == PR_NETADDR_SIZE(addr));
         	fd2->secret->md.accepted_socket = PR_TRUE;
         	memcpy(&fd2->secret->md.peer_addr, addr, al);
+#ifdef _PR_INET6
+		if (AF_INET6 == addr->raw.family)
+        	addr->raw.family = PR_AF_INET6;
+#endif
 	}
 	return fd2;
 }
 #endif /* WINNT */
 
 
 static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
 {
 	PRInt32 result;
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+	PRNetAddr addrCopy;
+#endif
 
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
 
 #ifdef XP_UNIX
 	if (addr->raw.family == AF_UNIX) {
 		/* Disallow relative pathnames */
 		if (addr->local.path[0] != '/') {
 			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
 			return PR_FAILURE;
 		}
 	}
 #endif /* XP_UNIX */
 
-	result = _PR_MD_BIND(fd, addr, PR_NETADDR_SIZE(addr));
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+	}
+#endif
+	result = _PR_MD_BIND(fd, addrp, PR_NETADDR_SIZE(addr));
 	if (result < 0) {
 		return PR_FAILURE;
 	}
 	return PR_SUCCESS;
 }
 
 static PRStatus PR_CALLBACK SocketListen(PRFileDesc *fd, PRIntn backlog)
 {
@@ -625,34 +653,45 @@ static PRStatus PR_CALLBACK SocketSync(P
 	return PR_SUCCESS;
 }
 
 static PRInt32 PR_CALLBACK SocketSendTo(
     PRFileDesc *fd, const void *buf, PRInt32 amount,
     PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
 {
 	PRInt32 temp, count;
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+	PRNetAddr addrCopy;
+#endif
 	PRThread *me = _PR_MD_CURRENT_THREAD();
 
 	if (_PR_PENDING_INTERRUPT(me)) {
 		me->flags &= ~_PR_INTERRUPT;
 		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
 		return -1;
 	}
 	if (_PR_IO_PENDING(me)) {
 		PR_SetError(PR_IO_PENDING_ERROR, 0);
 		return -1;
 	}
 
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+	}
+#endif
 
 	count = 0;
 	while (amount > 0) {
 		temp = _PR_MD_SENDTO(fd, buf, amount, flags,
-		    addr, PR_NETADDR_SIZE(addr), timeout);
+		    addrp, PR_NETADDR_SIZE(addr), timeout);
 		if (temp < 0) {
 					count = -1;
 					break;
 				}
 		count += temp;
 		if (fd->secret->nonblocking) {
 			break;
 		}
@@ -676,16 +715,20 @@ PRIntn flags, PRNetAddr *addr, PRInterva
 	}
 	if (_PR_IO_PENDING(me)) {
 		PR_SetError(PR_IO_PENDING_ERROR, 0);
 		return -1;
 	}
 
 	al = sizeof(PRNetAddr);
 	rv = _PR_MD_RECVFROM(fd, buf, amount, flags, addr, &al, timeout);
+#ifdef _PR_INET6
+	if (addr && (AF_INET6 == addr->raw.family))
+        addr->raw.family = PR_AF_INET6;
+#endif
 	return rv;
 }
 
 static PRInt32 PR_CALLBACK SocketAcceptRead(PRFileDesc *sd, PRFileDesc **nd, 
 PRNetAddr **raddr, void *buf, PRInt32 amount,
 PRIntervalTime timeout)
 {
 	PRInt32 rv;
@@ -725,16 +768,20 @@ PRIntervalTime timeout)
 			_PR_MD_CLOSE_SOCKET(newSock);
 			/* PR_AllocFileDesc() has invoked PR_SetError(). */
 			rv = -1;
 		} else {
 			(*nd)->secret->md.io_model_committed = PR_TRUE;
 			(*nd)->secret->md.accepted_socket = PR_TRUE;
 			memcpy(&(*nd)->secret->md.peer_addr, *raddr,
 				PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+			if (AF_INET6 == *raddr->raw.family)
+        		*raddr->raw.family = PR_AF_INET6;
+#endif
 		}
 	}
 	}
 #else
 	rv = _PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout);
 #endif
 	return rv;
 }
@@ -774,16 +821,20 @@ PRIntervalTime timeout)
 			_PR_MD_CLOSE_SOCKET(newSock);
 			/* PR_AllocFileDesc() has invoked PR_SetError(). */
 			rv = -1;
 		} else {
 			(*nd)->secret->md.io_model_committed = PR_TRUE;
 			(*nd)->secret->md.accepted_socket = PR_TRUE;
 			memcpy(&(*nd)->secret->md.peer_addr, *raddr,
 				PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+			if (AF_INET6 == *raddr->raw.family)
+        		*raddr->raw.family = PR_AF_INET6;
+#endif
 		}
 	}
 	return rv;
 }
 
 PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback(
 PRFileDesc *sd, PRFileDesc **nd, 
 PRNetAddr **raddr, void *buf, PRInt32 amount,
@@ -821,16 +872,20 @@ void *callbackArg)
 			_PR_MD_CLOSE_SOCKET(newSock);
 			/* PR_AllocFileDesc() has invoked PR_SetError(). */
 			rv = -1;
 		} else {
 			(*nd)->secret->md.io_model_committed = PR_TRUE;
 			(*nd)->secret->md.accepted_socket = PR_TRUE;
 			memcpy(&(*nd)->secret->md.peer_addr, *raddr,
 				PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+			if (AF_INET6 == *raddr->raw.family)
+        		*raddr->raw.family = PR_AF_INET6;
+#endif
 		}
 	}
 	return rv;
 }
 #endif /* WINNT */
 
 #ifdef WINNT
 PR_IMPLEMENT(void)
@@ -905,146 +960,44 @@ static PRStatus PR_CALLBACK SocketGetNam
 	PRInt32 result;
 	PRUint32 addrlen;
 
 	addrlen = sizeof(PRNetAddr);
 	result = _PR_MD_GETSOCKNAME(fd, addr, &addrlen);
 	if (result < 0) {
 		return PR_FAILURE;
 	}
+#ifdef _PR_INET6
+	if (AF_INET6 == addr->raw.family)
+        addr->raw.family = PR_AF_INET6;
+#endif
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
 	PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
 	return PR_SUCCESS;
 }
 
 static PRStatus PR_CALLBACK SocketGetPeerName(PRFileDesc *fd, PRNetAddr *addr)
 {
 	PRInt32 result;
 	PRUint32 addrlen;
 
 	addrlen = sizeof(PRNetAddr);
 	result = _PR_MD_GETPEERNAME(fd, addr, &addrlen);
 	if (result < 0) {
 		return PR_FAILURE;
 	}
+#ifdef _PR_INET6
+	if (AF_INET6 == addr->raw.family)
+        addr->raw.family = PR_AF_INET6;
+#endif
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
 	PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
 	return PR_SUCCESS;
 }
 
-static PRStatus PR_CALLBACK SocketGetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
-    PRInt32 level, name;
-    PRStatus rv;
-
-    /*
-     * PR_SockOpt_Nonblocking is a special case that does not
-     * translate to a getsockopt() call
-     */
-    if (PR_SockOpt_Nonblocking == optname)
-    {
-        PR_ASSERT(sizeof(PRIntn) <= *optlen);
-        *((PRIntn *) optval) = (PRIntn) fd->secret->nonblocking;
-        *optlen = sizeof(PRIntn);
-        return PR_SUCCESS;
-    }
-
-    rv = _PR_MapOptionName(optname, &level, &name);
-    if (PR_SUCCESS == rv)
-    {
-        if (PR_SockOpt_Linger == optname)
-        {
-#if !defined(XP_BEOS)
-            struct linger linger;
-            PRInt32 len = sizeof(linger);
-            rv = _PR_MD_GETSOCKOPT(
-                fd, level, name, (char *) &linger, &len);
-            if (PR_SUCCESS == rv)
-            {
-                ((PRLinger*)(optval))->polarity = linger.l_onoff
-                    ? PR_TRUE : PR_FALSE;
-                ((PRLinger*)(optval))->linger = PR_SecondsToInterval(
-                    linger.l_linger);
-                *optlen = sizeof(PRLinger);
-            }
-#else
-            PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
-            return PR_FAILURE;
-#endif
-        }
-        else
-        {
-            rv = _PR_MD_GETSOCKOPT(
-                fd, level, name, (char*)optval, optlen);
-        }
-    }
-    return rv;
-}
-
-static PRStatus PR_CALLBACK SocketSetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
-	PRInt32 level, name;
-    PRStatus rv;
-
-    /*
-     * PR_SockOpt_Nonblocking is a special case that does not
-     * translate to a setsockopt call.
-     */
-    if (PR_SockOpt_Nonblocking == optname)
-    {
-        PRBool fNonblocking = *((PRIntn *) optval) ? PR_TRUE : PR_FALSE;
-        PR_ASSERT(sizeof(PRIntn) == optlen);
-#ifdef WINNT
-        PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE)
-            || (fd->secret->nonblocking == fNonblocking));
-        if (fd->secret->md.io_model_committed
-            && (fd->secret->nonblocking != fNonblocking))
-        {
-            /*
-             * On NT, once we have associated a socket with the io
-             * completion port, we can't disassociate it.  So we
-             * can't change the nonblocking option of the socket
-             * afterwards.
-             */
-            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-            return PR_FAILURE;
-        }
-#endif
-        fd->secret->nonblocking = fNonblocking;
-        return PR_SUCCESS;
-    }
-
-    rv = _PR_MapOptionName(optname, &level, &name);
-    if (PR_SUCCESS == rv)
-    {
-        if (PR_SockOpt_Linger == optname)
-        {
-#if !defined(XP_BEOS)
-            struct linger linger;
-            linger.l_onoff = ((PRLinger*)(optval))->polarity ? 1 : 0;
-            linger.l_linger = PR_IntervalToSeconds(
-                ((PRLinger*)(optval))->linger);
-            rv = _PR_MD_SETSOCKOPT(
-                fd, level, name, (char *) &linger, sizeof(linger));
-#else
-            PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
-            return PR_FAILURE;
-#endif
-        }
-        else
-        {
-            rv = _PR_MD_SETSOCKOPT(
-                fd, level, name, (const char*)optval, optlen);
-        }
-    }
-    return rv;
-}
-
 static PRInt16 PR_CALLBACK SocketPoll(
     PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
 {
 #ifdef XP_MAC
 #pragma unused( fd, in_flags )
 #endif
     *out_flags = 0;
     return in_flags;
@@ -1072,18 +1025,18 @@ static PRIOMethods tcpMethods = {
 	SocketSend,
 	(PRRecvfromFN)_PR_InvalidInt,
 	(PRSendtoFN)_PR_InvalidInt,
 	SocketPoll,
 	SocketAcceptRead,
 	SocketTransmitFile,
 	SocketGetName,
 	SocketGetPeerName,
-	SocketGetSockOpt,
-	SocketSetSockOpt,
+	(PRReservedFN)_PR_InvalidInt,
+	(PRReservedFN)_PR_InvalidInt,
 	_PR_SocketGetSocketOption,
 	_PR_SocketSetSocketOption,
     SocketSendFile, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -1111,18 +1064,18 @@ static PRIOMethods udpMethods = {
 	SocketSend,
 	SocketRecvFrom,
 	SocketSendTo,
 	SocketPoll,
 	(PRAcceptreadFN)_PR_InvalidInt,
 	(PRTransmitfileFN)_PR_InvalidInt,
 	SocketGetName,
 	SocketGetPeerName,
-	SocketGetSockOpt,
-	SocketSetSockOpt,
+	(PRReservedFN)_PR_InvalidInt,
+	(PRReservedFN)_PR_InvalidInt,
 	_PR_SocketGetSocketOption,
 	_PR_SocketSetSocketOption,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -1151,18 +1104,18 @@ static PRIOMethods socketpollfdMethods =
     (PRSendFN)_PR_InvalidInt,        
     (PRRecvfromFN)_PR_InvalidInt,    
     (PRSendtoFN)_PR_InvalidInt,        
 	SocketPoll,
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,    
     (PRGetpeernameFN)_PR_InvalidStatus,    
-    (PRGetsockoptFN)_PR_InvalidStatus,    
-    (PRSetsockoptFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
     (PRGetsocketoptionFN)_PR_InvalidStatus,
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -1178,73 +1131,117 @@ PR_IMPLEMENT(const PRIOMethods*) PR_GetU
 	return &udpMethods;
 }
 
 static const PRIOMethods* PR_GetSocketPollFdMethods()
 {
     return &socketpollfdMethods;
 }  /* PR_GetSocketPollFdMethods */
 
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd);
+
+#if defined(_PR_INET6_PROBE)
+
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+
+PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket()
+{
+PRInt32 osfd;
+
+	osfd = _PR_MD_SOCKET(AF_INET6, SOCK_STREAM, 0);
+	if (osfd != -1) {
+		_PR_MD_CLOSE_SOCKET(osfd);
+		return PR_TRUE;
+	}
+	return PR_FALSE;
+}
+#endif	/* _PR_INET6_PROBE */
+
+#endif
 
 PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
 {
 	PRInt32 osfd;
 	PRFileDesc *fd;
+	PRInt32 tmp_domain = domain;
 
 	if (!_pr_initialized) _PR_ImplicitInitialization();
-	if (AF_INET != domain
-#if defined(_PR_INET6)
-			&& AF_INET6 != domain
-#endif
+	if (PR_AF_INET != domain
+			&& PR_AF_INET6 != domain
 #if defined(XP_UNIX)
-			&& AF_UNIX != domain
+			&& PR_AF_LOCAL != domain
 #endif
 			) {
 		PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
 		return NULL;
 	}
+
+#if defined(_PR_INET6)
+	if (PR_AF_INET6 == domain) {
+#if defined(_PR_INET6_PROBE)
+        if (_pr_ipv6_is_present == PR_FALSE) 
+            domain = AF_INET;
+        else
+#endif
+		domain = AF_INET6;
+    }
+#elif defined(_PR_INET6_PROBE)
+	if (PR_AF_INET6 == domain) {
+		if (_pr_ipv6_is_present == PR_FALSE) 
+			domain = AF_INET;
+		else
+			domain = AF_INET6;
+	}
+#else
+	if (PR_AF_INET6 == domain)
+		domain = AF_INET;
+#endif	/* _PR_INET6 */
 	osfd = _PR_MD_SOCKET(domain, type, proto);
 	if (osfd == -1) {
 		return 0;
 	}
 	if (type == SOCK_STREAM)
 		fd = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
 	else
 		fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods());
 	/*
 	 * Make the sockets non-blocking
 	 */
-	if (fd != NULL)
+	if (fd != NULL) {
 		_PR_MD_MAKE_NONBLOCK(fd);
-	else
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+		/*
+		 * For platforms with no support for IPv6 
+		 * create layered socket for IPv4-mapped IPv6 addresses
+		 */
+		if (PR_AF_INET6 == tmp_domain && PR_AF_INET == domain) {
+			if (PR_FAILURE == _pr_push_ipv6toipv4_layer(fd)) {
+				PR_Close(fd);
+				fd = NULL;
+			}
+		}
+#endif
+	} else
 		_PR_MD_CLOSE_SOCKET(osfd);
+
 	return fd;
 }
 
 PR_IMPLEMENT(PRFileDesc *) PR_NewTCPSocket(void)
 {
 	PRInt32 domain = AF_INET;
 
-#if defined(_PR_INET6)
-	if (_pr_ipv6_enabled) {
-		domain = AF_INET6;
-	}
-#endif
 	return PR_Socket(domain, SOCK_STREAM, 0);
 }
 
 PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void)
 {
 	PRInt32 domain = AF_INET;
 
-#if defined(_PR_INET6)
-	if (_pr_ipv6_enabled) {
-		domain = AF_INET6;
-	}
-#endif
 	return PR_Socket(domain, SOCK_DGRAM, 0);
 }
 
 PR_IMPLEMENT(PRFileDesc *) PR_OpenTCPSocket(PRIntn af)
 {
 	return PR_Socket(af, SOCK_STREAM, 0);
 }
 
--- a/pr/src/linking/prlink.c
+++ b/pr/src/linking/prlink.c
@@ -255,16 +255,17 @@ void _PR_ShutdownLinker(void)
 #endif
 
 /******************************************************************************/
 
 PR_IMPLEMENT(PRStatus) PR_SetLibraryPath(const char *path)
 {
     PRStatus rv = PR_SUCCESS;
 
+    if (!_pr_initialized) _PR_ImplicitInitialization();
     PR_EnterMonitor(pr_linker_lock);
     PR_FREEIF(_pr_currentLibPath);
     if (path) {
         _pr_currentLibPath = strdup(path);
         if (!_pr_currentLibPath) {
             PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
         rv = PR_FAILURE;
         }
@@ -279,16 +280,17 @@ PR_IMPLEMENT(PRStatus) PR_SetLibraryPath
 ** Return the library path for finding shared libraries.
 */
 PR_IMPLEMENT(char *) 
 PR_GetLibraryPath()
 {
     char *ev;
     char *copy = NULL;  /* a copy of _pr_currentLibPath */
 
+    if (!_pr_initialized) _PR_ImplicitInitialization();
     PR_EnterMonitor(pr_linker_lock);
     if (_pr_currentLibPath != NULL) {
         goto exit;
     }
 
     /* initialize pr_currentLibPath */
 
 #ifdef XP_PC
@@ -792,16 +794,17 @@ pr_LoadLibraryByPathname(const char *nam
     return result;
 }
 
 PR_IMPLEMENT(PRLibrary*) 
 PR_FindLibrary(const char *name)
 {
     PRLibrary* result;
 
+    if (!_pr_initialized) _PR_ImplicitInitialization();
     PR_EnterMonitor(pr_linker_lock);
     result = pr_UnlockedFindLibrary(name);
     PR_ExitMonitor(pr_linker_lock);
     return result;
 }
 
 
 #ifdef XP_MAC
@@ -1138,16 +1141,17 @@ PR_FindSymbolAndLibrary(const char *raw_
     void *f = NULL;
 #if defined(NEED_LEADING_UNDERSCORE)
     char *name;
 #else
     const char *name;
 #endif
     PRLibrary* lm;
 
+    if (!_pr_initialized) _PR_ImplicitInitialization();
     /*
     ** Mangle the raw symbol name in any way that is platform specific.
     */
 #if defined(NEED_LEADING_UNDERSCORE)
     /* Need a leading _ */
     name = PR_smprintf("_%s", raw_name);
 #elif defined(AIX)
     /*
--- a/pr/src/md/mac/macsocket.h
+++ b/pr/src/md/mac/macsocket.h
@@ -159,18 +159,16 @@ extern int select (int nfds, fd_set *rea
 #define macsock_read PR_Read
 #define macsock_close PR_Close
 #define macsock_accept PR_Accept
 #define macsock_bind PR_Bind
 #define macsock_listen PR_Listen
 #define macsock_shutdown PR_Shutdown
 #define macsock_getpeername PR_GetPeerName
 #define macsock_getsockname PR_GetSockName
-#define macsock_getsockopt PR_GetSockOpt
-#define macsock_setsockopt PR_SetSockOpt
 #define macsock_socketavailable PR_SocketAvailable
 #define macsock_send PR_Send
 #define macsock_sendto PR_SendTo
 #define macsock_recvfrom PR_RecvFrom
 #define macsock_recv PR_Recv
 
 #ifdef __cplusplus
 }
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -238,28 +238,44 @@ static void macsock_map_error(OSStatus e
 static void PrepareForAsyncCompletion(PRThread * thread, PRInt32 osfd)
 {
     thread->io_pending       = PR_TRUE;
     thread->io_fd            = osfd;
     thread->md.osErrCode     = noErr;
 }
 
 
+static void
+WakeUpNotifiedThread(PRThread *thread, OTResult result)
+{
+    _PRCPU *      cpu      = _PR_MD_CURRENT_CPU(); 
+
+	if (thread) {
+		thread->md.osErrCode = result;
+		if (_PR_MD_GET_INTSOFF()) {
+			cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+			thread->md.missedIONotify = PR_TRUE;
+			return;
+		}
+		DoneWaitingOnThisThread(thread);
+	}
+}
+
 // Notification routine
 // Async callback routine.
 // A5 is OK. Cannot allocate memory here
 pascal void  NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
 {
 	PRFilePrivate *secret  = (PRFilePrivate *) contextPtr;
 	_MDFileDesc * md       = &(secret->md);
 	EndpointRef   endpoint = (EndpointRef)secret->md.osfd;
     PRThread *    thread   = NULL;
-    _PRCPU *      cpu      = _PR_MD_CURRENT_CPU(); 
 	OSStatus      err;
 	OTResult	  resultOT;
+    TDiscon		  discon;
 
     switch (code)
     {
 // OTLook Events - 
         case T_LISTEN:        // A connection request is available
         	// If md->doListen is true, then PR_Listen has been
         	// called on this endpoint; therefore, we're ready to
         	// accept connections. But we'll do that with PR_Accept
@@ -298,36 +314,59 @@ pascal void  NotifierRoutine(void * cont
             secret->md.read.cookie    = cookie;
 			break;
 
         case T_EXDATA:      // Expedited data is available
             PR_ASSERT(!"T_EXDATA Not implemented");
 			return;
 
         case T_DISCONNECT:  // A disconnect is available
-            err = OTRcvDisconnect(endpoint, NULL);
+            discon.udata.len = 0;
+            err = OTRcvDisconnect(endpoint, &discon);
             PR_ASSERT(err == kOTNoError);
             secret->md.exceptReady     = PR_TRUE;
             secret->md.connectionOpen  = PR_FALSE;
+
+			// wake up waiting threads, if any
+			result = -3199 - discon.reason; // obtain the negative error code
+
+            if ((thread = secret->md.read.thread) != NULL) {
+		        secret->md.read.thread    = NULL;
+    	        secret->md.read.cookie    = cookie;
+            	WakeUpNotifiedThread(thread, result);
+    	    }
+            
+            if ((thread = secret->md.write.thread) != NULL) {
+	            secret->md.write.thread    = NULL;
+	            secret->md.write.cookie    = cookie;
+	            WakeUpNotifiedThread(thread, result);
+	        }
+	        
+	        thread = NULL; // already took care of notification here
             break;
 		
         case T_ERROR:       // obsolete/unused in library
             PR_ASSERT(!"T_ERROR Not implemented");
 			return;		
 		
         case T_UDERR:       // UDP Send error; clear the error
 			(void) OTRcvUDErr((EndpointRef) cookie, NULL);
             break;
 
         case T_ORDREL:      // An orderly release is available
             err = OTRcvOrderlyDisconnect(endpoint);
             PR_ASSERT(err == kOTNoError);
             secret->md.readReady      = PR_TRUE;   // mark readable (to emulate bsd sockets)
             // remember connection is closed, so we can return 0 on read or receive
 			secret->md.connectionOpen = PR_FALSE;
+	
+            thread = secret->md.read.thread;
+	        secret->md.read.thread    = NULL;
+	        secret->md.read.cookie    = cookie;
+
             break;		
 
         case T_GODATA:   // Flow control lifted on standard data
             secret->md.writeReady = PR_TRUE;
 			resultOT = OTLook(endpoint);		// clear T_GODATA event
 			PR_ASSERT(resultOT == T_GODATA);
 			
 			// wake up waiting thread, if any
@@ -386,26 +425,17 @@ pascal void  NotifierRoutine(void * cont
 //      case T_DNRMAILEXCHANGECOMPLETE:
 //      case T_DNRQUERYCOMPLETE:
         default:
         	// we should probably have a bit more sophisticated handling of kOTSystemSleep, etc.
 			// PR_ASSERT(code != 0);
             return;
     }
 
-	if (thread) {
-		thread->md.osErrCode = result;
-		if (_PR_MD_GET_INTSOFF()) {
-			cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
-			thread->md.missedIONotify = PR_TRUE;
-			return;
-		}
-
-		DoneWaitingOnThisThread(thread);
-	}
+	WakeUpNotifiedThread(thread, result);
 }
 
 
 static OSErr CreateSocket(int type, EndpointRef *endpoint)
 {
     OSStatus err;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     char *  configName;
@@ -579,16 +609,17 @@ PRInt32 _MD_listen(PRFileDesc *fd, PRInt
     if (backlog == 0)
         backlog = 1;
 
     if (endpoint == NULL) {
         err = EBADF;
         goto ErrorExit;
     }
         
+    addr.inet.family = AF_INET;
     addr.inet.port = addr.inet.ip = 0;
 
     bindReq.addr.maxlen = PR_NETADDR_SIZE (&addr);
     bindReq.addr.len = 0;
     bindReq.addr.buf = (UInt8*) &addr;
     bindReq.qlen = 0;
     
     PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
@@ -662,22 +693,16 @@ PRInt32 _MD_getsockname(PRFileDesc *fd, 
         goto ErrorExit;
     }
         
     if (addr == NULL) {
         err = kEFAULTErr;
         goto ErrorExit;
     }
 
-#if !defined(_PR_INET6)        
-    addr->inet.family = AF_INET;
-#endif
-    
-    PR_ASSERT(PR_NETADDR_SIZE(addr) >= (*addrlen));
-
     bindReq.addr.len = *addrlen;
     bindReq.addr.maxlen = *addrlen;
     bindReq.addr.buf = (UInt8*) addr;
     bindReq.qlen = 0;
     
 	PR_Lock(fd->secret->md.miscLock);
     PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
 	fd->secret->md.misc.thread = me;
@@ -691,16 +716,17 @@ PRInt32 _MD_getsockname(PRFileDesc *fd, 
 
     WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
 	PR_Unlock(fd->secret->md.miscLock);
 
     err = me->md.osErrCode;
     if (err != kOTNoError)
         goto ErrorExit;
 
+    *addrlen = PR_NETADDR_SIZE(addr);
     return kOTNoError;
 
 ErrorExit:
     macsock_map_error(err);
     return -1;
 }
 
 
@@ -983,17 +1009,17 @@ PRInt32 _MD_socketavailable(PRFileDesc *
         err = kEBADFErr;
         goto ErrorExit;
     }
     
     bytes = 0;
     
     err = OTCountDataBytes(endpoint, &bytes);
     if ((err == kOTLookErr) ||         // Not really errors, we just need to do a read,
-        (err == kOTNoDataErr))        // or there’s nothing there.
+        (err == kOTNoDataErr))        // or there's nothing there.
         err = kOTNoError;
         
     if (err != kOTNoError)
         goto ErrorExit;
         
     return bytes;
 
 ErrorExit:
@@ -1122,19 +1148,25 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNet
 
     if (endpoint == NULL) {
         err = kEBADFErr;
         goto ErrorExit;
     }
         
     memset(&call, 0 , sizeof(call));
 
-    call.addr.maxlen = PR_NETADDR_SIZE(&callAddr);
-    call.addr.len = PR_NETADDR_SIZE(&callAddr);
-    call.addr.buf = (UInt8*) &callAddr;
+    if (addr != NULL) {
+        call.addr.maxlen = *addrlen;
+        call.addr.len = *addrlen;
+        call.addr.buf = (UInt8*) addr;
+    } else {
+        call.addr.maxlen = sizeof(callAddr);
+        call.addr.len = sizeof(callAddr);
+        call.addr.buf = (UInt8*) &callAddr;
+    }
 
 	do {
 	    PrepareForAsyncCompletion(me, fd->secret->md.osfd);
 	    fd->secret->md.misc.thread = me;
 	    
 	    // Perform the listen. 
 	    err = OTListen (endpoint, &call);
 	    if (err == kOTNoError)
@@ -1164,16 +1196,17 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNet
 	
 	err = OTInstallNotifier((ProviderRef) newosfd, RawEndpointNotifierRoutine, endthr);
     PR_ASSERT(err == kOTNoError);
     
 	err = OTSetAsynchronous((EndpointRef) newosfd);
 	PR_ASSERT(err == kOTNoError);
 
     // Bind to a local port; let the system assign it.
+    bindAddr.inet.family = AF_INET;
     bindAddr.inet.port = bindAddr.inet.ip = 0;
 
     bindReq.addr.maxlen = PR_NETADDR_SIZE (&bindAddr);
     bindReq.addr.len = 0;
     bindReq.addr.buf = (UInt8*) &bindAddr;
     bindReq.qlen = 0;
 
     PrepareForAsyncCompletion(me, newosfd);    
@@ -1194,18 +1227,16 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNet
         goto ErrorExit;
 
     WaitOnThisThread(me, timeout);
 
     err = me->md.osErrCode;
     if (err != kOTNoError)
         goto ErrorExit;
 
-    if (addr != NULL)
-        *addr = callAddr;
     if (addrlen != NULL)
         *addrlen = call.addr.len;
 
 	// Remove the temporary notifier we installed to set up the new endpoint.
 	OTRemoveNotifier((EndpointRef) newosfd);
 	PR_Free(endthr); // free the temporary context we set up for this endpoint
 
     return newosfd;
@@ -1235,16 +1266,17 @@ PRInt32 _MD_connect(PRFileDesc *fd, PRNe
         
     if (addr == NULL) {
         err = kEFAULTErr;
         goto ErrorExit;
     }
         
     // Bind to a local port; let the system assign it.
 
+    bindAddr.inet.family = AF_INET;
     bindAddr.inet.port = bindAddr.inet.ip = 0;
 
     bindReq.addr.maxlen = PR_NETADDR_SIZE (&bindAddr);
     bindReq.addr.len = 0;
     bindReq.addr.buf = (UInt8*) &bindAddr;
     bindReq.qlen = 0;
     
 	PR_Lock(fd->secret->md.miscLock);
@@ -1779,17 +1811,17 @@ PR_IMPLEMENT(PRStatus)
 _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
 {
     PRThread *me = _PR_MD_CURRENT_THREAD();
 	EndpointRef ep = (EndpointRef) fd->secret->md.osfd;
 	InetAddress inetAddr;
 	TBind peerAddr;
 	OSErr err;
 	
-	if (*addrlen < PR_NETADDR_SIZE(addr)) {
+	if (*addrlen < sizeof(InetAddress)) {
 
 		err = (OSErr) kEINVALErr;
 		goto ErrorExit;
 	}
 
     peerAddr.addr.maxlen = sizeof(InetAddress);
     peerAddr.addr.len = 0;
     peerAddr.addr.buf = (UInt8*) &inetAddr;
--- a/pr/src/md/mac/prcpucfg.h
+++ b/pr/src/md/mac/prcpucfg.h
@@ -21,16 +21,18 @@
 
 #ifndef XP_MAC
 #define XP_MAC
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 
+#define PR_AF_INET6 30  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1L
 #define PR_BYTES_PER_SHORT  2L
 #define PR_BYTES_PER_INT    4L
 #define PR_BYTES_PER_INT64  8L
 #define PR_BYTES_PER_LONG   4L
 #define PR_BYTES_PER_FLOAT  4L
 #define PR_BYTES_PER_DOUBLE 8L
 #define PR_BYTES_PER_WORD   4L
--- a/pr/src/md/windows/Makefile
+++ b/pr/src/md/windows/Makefile
@@ -35,16 +35,17 @@ CSRCS = \
     w16stdio.c  \
     w16callb.c \
     ntinrval.c \
     $(NULL)
 else
 ifeq ($(OS_TARGET), WIN95)
 CSRCS =          \
     ntmisc.c \
+    ntsec.c   \
     ntsem.c   \
     ntinrval.c \
     ntgc.c \
 	w95thred.c \
 	w95io.c \
 	w95cv.c \
 	w32rng.c \
 	w95sock.c \
@@ -53,16 +54,17 @@ CSRCS =          \
     w32poll.c \
     w32shm.c \
     w95dllmain.c \
     $(NULL)
 else
 CSRCS =          \
     ntdllmn.c \
     ntmisc.c \
+    ntsec.c   \
     ntsem.c   \
     ntinrval.c \
     ntgc.c \
     ntthread.c \
     ntio.c    \
 	win32_errors.c \
     w32ipcsem.c \
     w32poll.c \
--- a/pr/src/md/windows/ntio.c
+++ b/pr/src/md/windows/ntio.c
@@ -32,16 +32,17 @@
  * be incorrectly completed on the GLOBAL_SCOPE IO thread; this will mean
  * extra context switching; but I don't think there is anything I can do
  * about it.
  */
 
 #include "primpl.h"
 #include "pprmwait.h"
 #include <direct.h>
+#include <mbstring.h>
 
 static HANDLE                _pr_completion_port;
 static PRThread             *_pr_io_completion_thread;
 
 #define RECYCLE_SIZE 512
 static struct _MDLock        _pr_recycle_lock;
 static PRInt32               _pr_recycle_array[RECYCLE_SIZE];
 static PRInt32               _pr_recycle_tail = 0; 
@@ -55,36 +56,50 @@ PRBool                       _nt_version
 struct _MDLock               _pr_ioq_lock;
 extern _MDLock               _nt_idleLock;
 extern PRCList               _nt_idleList;
 extern PRUint32              _nt_idleCount;
 
 #define CLOSE_TIMEOUT   PR_SecondsToInterval(5)
 
 /*
+ * NSPR-to-NT access right mapping table for files.
+ */
+static DWORD fileAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
+ * NSPR-to-NT access right mapping table for directories.
+ */
+static DWORD dirAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE|FILE_DELETE_CHILD,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
  * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
  * We store the value in a PRTime variable for convenience.
  * This constant is used by _PR_FileTimeToPRTime().
  */
 static const PRTime _pr_filetime_offset = 116444736000000000i64;
 
 #define _NEED_351_FILE_LOCKING_HACK
 #ifdef _NEED_351_FILE_LOCKING_HACK
 #define _PR_LOCAL_FILE 1
 #define _PR_REMOTE_FILE 2
 PRBool IsFileLocalInit();
 PRInt32 IsFileLocal(HANDLE hFile);
 #endif /* _NEED_351_FILE_LOCKING_HACK */
 
 static PRInt32 _md_MakeNonblock(HANDLE);
 
-/* The _nt_use_async flag is used to prevent nspr from using any async io.
- * this is a temporary hack.  Don't learn to rely on it.
- */
-static int _nt_use_async = 1;
 PRInt32 _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr_in *addr, int *len, PRIntervalTime);
 PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
 PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
 PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime);
 PRInt32 _nt_nonblock_sendto(PRFileDesc *, const char *, int, const struct sockaddr *, int, PRIntervalTime);
 PRInt32 _nt_nonblock_recvfrom(PRFileDesc *, char *, int, struct sockaddr *, int *, PRIntervalTime);
 
 /*
@@ -884,16 +899,18 @@ void
         systime.wSecond = 0;
         systime.wMilliseconds = 0;
 
         rv = SystemTimeToFileTime(&systime, &filetime.ft);
         PR_ASSERT(0 != rv);
         PR_ASSERT(filetime.prt == _pr_filetime_offset);
     }
 #endif /* DEBUG */
+
+    _PR_NT_InitSids();
 }
 
 /* --- SOCKET IO --------------------------------------------------------- */
 
 /* _md_get_recycled_socket()
  * Get a socket from the recycle bin; if no sockets are in the bin,
  * create one.  The socket will be passed to AcceptEx() as the
  * second argument.
@@ -908,21 +925,16 @@ static SOCKET
     if (_pr_recycle_tail) {
         _pr_recycle_tail--;
         rv = _pr_recycle_array[_pr_recycle_tail];
         _MD_UNLOCK(&_pr_recycle_lock);
         return rv;
     }
     _MD_UNLOCK(&_pr_recycle_lock);
 
-#ifdef _PR_INET6
-    if (_pr_ipv6_enabled) {
-        af = AF_INET6;
-    }
-#endif
     rv = _PR_MD_SOCKET(af, SOCK_STREAM, 0);
     if (rv != INVALID_SOCKET && _md_Associate((HANDLE)rv) == 0) {
         closesocket(rv);
         return INVALID_SOCKET;
     }
     return rv;
 }
 
@@ -1122,17 +1134,17 @@ PRInt32
                PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     PRInt32 rv;
     PRThread *cThread;
     struct connect_data_s cd;
 
-    if (!_nt_use_async || fd->secret->nonblocking) {
+    if (fd->secret->nonblocking) {
         PRInt32 rv;
         fd_set wd;
         struct timeval tv, *tvp;
 
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
@@ -1289,29 +1301,29 @@ PRInt32
     PRThread *me = _PR_MD_CURRENT_THREAD();
     SOCKET accept_sock;
     int bytes;
     PRNetAddr *Laddr;
     PRNetAddr *Raddr;
     PRUint32 llen, err;
     int rv;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         /*
          * The accepted socket inherits the nonblocking and
          * inheritable (HANDLE_FLAG_INHERIT) attributes of
          * the listening socket.
          */
         accept_sock = _nt_nonblock_accept(fd, (struct sockaddr_in *)raddr, rlen, timeout);
-        if (_nt_use_async && !fd->secret->nonblocking) {
+        if (!fd->secret->nonblocking) {
             u_long zero = 0;
 
             rv = ioctlsocket(accept_sock, FIONBIO, &zero);
             PR_ASSERT(0 == rv);
         }
         return accept_sock;
     }
 
@@ -1436,31 +1448,16 @@ PRInt32
     PRThread *me = _PR_MD_CURRENT_THREAD();
     int bytes;
     PRNetAddr *Laddr;
     PRUint32 llen, rlen, err;
     int rv;
     PRBool isConnected;
     PRBool madeCallback = PR_FALSE;
 
-    if (!_nt_use_async) {
-        PRFileDesc *nd;
-        bytes = _PR_EmulateAcceptRead(sd, &nd, raddr, buf, amount, timeout);
-        if (bytes != -1) {
-            /*
-             * This part is the same as SocketClose(nd), except
-             * that we don't close the osfd.
-             */
-            PR_ASSERT(nd->secret->state == _PR_FILEDESC_OPEN);
-            *newSock = nd->secret->md.osfd;
-            PR_FreeFileDesc(nd);
-        }
-        return bytes;
-    }
-
     if (me->io_suspended) {
         PR_SetError(PR_INVALID_STATE_ERROR, 0);
         return -1;
     }
 
     if (!sd->secret->md.io_model_committed) {
         rv = _md_Associate((HANDLE)sock);
         PR_ASSERT(0 != rv);
@@ -1615,25 +1612,16 @@ retry:
 PRInt32
 _PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd,
 					PRInt32 flags, PRIntervalTime timeout)
 {
     PRThread *me = _PR_MD_CURRENT_THREAD();
     PRInt32 tflags;
     int rv, err;
 
-    if (!_nt_use_async) {
-        if (!sock->secret->md.io_model_committed) {
-            rv = _md_MakeNonblock((HANDLE)sock->secret->md.osfd);
-            PR_ASSERT(0 != rv);
-            sock->secret->md.io_model_committed = PR_TRUE;
-        }
-        return _PR_EmulateSendFile(sock, sfd, flags, timeout);
-    }
-
     if (me->io_suspended) {
         PR_SetError(PR_INVALID_STATE_ERROR, 0);
         return -1;
     }
 
     if (!sock->secret->md.io_model_committed) {
         rv = _md_Associate((HANDLE)sock->secret->md.osfd);
         PR_ASSERT(0 != rv);
@@ -1730,17 +1718,17 @@ PRInt32
 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
             PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     int bytes;
     int rv, err;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         return _nt_nonblock_recv(fd, buf, amount, timeout);
     }
 
@@ -1829,17 +1817,17 @@ PRInt32
 _PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
             PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     int bytes;
     int rv, err;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         return _nt_nonblock_send(fd, (char *)buf, amount, timeout);
     }
 
@@ -1927,17 +1915,17 @@ PRInt32
     PRInt32 osfd = fd->secret->md.osfd;
     PRInt32 rv;
 
     if (!fd->secret->md.io_model_committed) {
         rv = _md_MakeNonblock((HANDLE)osfd);
         PR_ASSERT(0 != rv);
         fd->secret->md.io_model_committed = PR_TRUE;
     }
-    if (_nt_use_async && !fd->secret->nonblocking && !fd->secret->inheritable)
+    if (!fd->secret->nonblocking && !fd->secret->inheritable)
         return pt_SendTo(osfd, buf, amount, flags, addr, addrlen, timeout);
     else
         return _nt_nonblock_sendto(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
 }
 
 PRInt32
 _PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
                 PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
@@ -1945,32 +1933,32 @@ PRInt32
     PRInt32 osfd = fd->secret->md.osfd;
     PRInt32 rv;
 
     if (!fd->secret->md.io_model_committed) {
         rv = _md_MakeNonblock((HANDLE)osfd);
         PR_ASSERT(0 != rv);
         fd->secret->md.io_model_committed = PR_TRUE;
     }
-    if (_nt_use_async && !fd->secret->nonblocking && !fd->secret->inheritable)
+    if (!fd->secret->nonblocking && !fd->secret->inheritable)
         return pt_RecvFrom(osfd, buf, amount, flags, addr, addrlen, timeout);
     else
         return _nt_nonblock_recvfrom(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
 }
 
 /* XXXMB - for now this is a sockets call only */
 PRInt32
 _PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     int index;
     int sent = 0;
     int rv;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         return _nt_nonblock_writev(fd, iov, iov_size, timeout);
     }
 
@@ -2110,126 +2098,154 @@ PRInt32
 {
     HANDLE file;
     PRInt32 access = 0;
     PRInt32 flags = 0;
     PRInt32 flag6 = 0;
     
     if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
  
-    if (_nt_use_async)
-    {
-        if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
-        if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
-
-        if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
-            flags = CREATE_NEW;
-        else if (osflags & PR_CREATE_FILE)
-            flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
-        else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
-        else flags = OPEN_EXISTING;
-
-        
-        flag6 |= FILE_FLAG_OVERLAPPED;
-
-        file = CreateFile(name, 
-                          access, 
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          NULL,
-                          flags, 
-                          flag6,
-                          NULL);
-        if (file == INVALID_HANDLE_VALUE) {
-            _PR_MD_MAP_OPEN_ERROR(GetLastError());
+    if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE)
+        flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
+    else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
+    else flags = OPEN_EXISTING;
+
+
+    flag6 |= FILE_FLAG_OVERLAPPED;
+
+    file = CreateFile(name, 
+                      access, 
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      NULL,
+                      flags, 
+                      flag6,
+                      NULL);
+    if (file == INVALID_HANDLE_VALUE) {
+        _PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (osflags & PR_APPEND) {
+        if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+            _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+            CloseHandle(file);
             return -1;
         }
-
-        if (osflags & PR_APPEND) {
-            if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
-                _PR_MD_MAP_LSEEK_ERROR(GetLastError());
-                CloseHandle(file);
-                return -1;
-            }
-        }
-
-        return (PRInt32)file;
     }
-    else
-    {
-   
-        if (osflags & PR_RDONLY || osflags & PR_RDWR)
-            access |= GENERIC_READ;
-        if (osflags & PR_WRONLY || osflags & PR_RDWR)
-            access |= GENERIC_WRITE;
-
-        if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
-            flags = CREATE_NEW;
-        else if (osflags & PR_CREATE_FILE) {
-            if (osflags & PR_TRUNCATE)
-                flags = CREATE_ALWAYS;
-            else
-                flags = OPEN_ALWAYS;
-        } else {
-            if (osflags & PR_TRUNCATE)
-                flags = TRUNCATE_EXISTING;
-            else
-                flags = OPEN_EXISTING;
+
+    return (PRInt32)file;
+}
+
+PRInt32
+_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+ 
+    if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE)
+        flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
+    else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
+    else flags = OPEN_EXISTING;
+
+
+    flag6 |= FILE_FLAG_OVERLAPPED;
+
+    if (osflags & PR_CREATE_FILE) {
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
         }
-
-        file = CreateFile(name,
-                          access,
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          NULL,
-                          flags,
-                          flag6,
-                          NULL);
-        if (file == INVALID_HANDLE_VALUE) {
-            _PR_MD_MAP_OPEN_ERROR(GetLastError());
-            return -1; 
+    }
+    file = CreateFile(name, 
+                      access, 
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      lpSA,
+                      flags, 
+                      flag6,
+                      NULL);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (file == INVALID_HANDLE_VALUE) {
+        _PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (osflags & PR_APPEND) {
+        if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+            _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+            CloseHandle(file);
+            return -1;
         }
-
-        return (PRInt32)file;
     }
+
+    return (PRInt32)file;
 }
 
 PRInt32 
 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
 {
     PRInt32 f = fd->secret->md.osfd;
     PRUint32 bytes;
     int rv, err;
-
-    if (_nt_use_async && !fd->secret->md.sync_file_io) {
+    LONG hiOffset = 0;
+    LONG loOffset;
+
+    if (!fd->secret->md.sync_file_io) {
         PRThread *me = _PR_MD_CURRENT_THREAD();
 
         if (me->io_suspended) {
             PR_SetError(PR_INVALID_STATE_ERROR, 0);
             return -1;
         }
 
         memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
 
-        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, 0, FILE_CURRENT);
+        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+        PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
 
         if (fd->secret->inheritable) {
             rv = ReadFile((HANDLE)f, 
                           (LPVOID)buf, 
                           len, 
                           &bytes, 
                           &me->md.overlapped.overlapped);
             if (rv != 0) {
-                SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+                loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
                 return bytes;
             }
             err = GetLastError();
             if (err == ERROR_IO_PENDING) {
                 rv = GetOverlappedResult((HANDLE)f,
                         &me->md.overlapped.overlapped, &bytes, TRUE);
                 if (rv != 0) {
-                    SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+                    loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                    PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
                     return bytes;
                 }
                 err = GetLastError();
             }
             if (err == ERROR_HANDLE_EOF) {
                 return 0;
             } else {
                 _PR_MD_MAP_READ_ERROR(err);
@@ -2337,45 +2353,50 @@ PRInt32
 }
 
 PRInt32
 _PR_MD_WRITE(PRFileDesc *fd, void *buf, PRInt32 len)
 {
     PRInt32 f = fd->secret->md.osfd;
     PRInt32 bytes;
     int rv, err;
-
-    if (_nt_use_async && !fd->secret->md.sync_file_io) {
+    LONG hiOffset = 0;
+    LONG loOffset;
+
+    if (!fd->secret->md.sync_file_io) {
         PRThread *me = _PR_MD_CURRENT_THREAD();
 
         if (me->io_suspended) {
             PR_SetError(PR_INVALID_STATE_ERROR, 0);
             return -1;
         }
 
         memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
 
-        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, 0, FILE_CURRENT);
+        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+        PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
 
         if (fd->secret->inheritable) {
             rv = WriteFile((HANDLE)f, 
                           (LPVOID)buf, 
                           len, 
                           &bytes, 
                           &me->md.overlapped.overlapped);
             if (rv != 0) {
-                SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+                loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
                 return bytes;
             }
             err = GetLastError();
             if (err == ERROR_IO_PENDING) {
                 rv = GetOverlappedResult((HANDLE)f,
                         &me->md.overlapped.overlapped, &bytes, TRUE);
                 if (rv != 0) {
-                    SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+                    loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                    PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
                     return bytes;
                 }
                 err = GetLastError();
             }
             _PR_MD_MAP_READ_ERROR(err);
             return -1;
         } else {
             if (!fd->secret->md.io_model_committed) {
@@ -2582,72 +2603,60 @@ PRInt32
     }
     return 0;
 }
 
 PRInt32
 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket)
 {
     PRInt32 rv;
-    if (_nt_use_async) {
-        PRThread *me = _PR_MD_CURRENT_THREAD();
-
-        if (socket)  {
-            rv = closesocket((SOCKET)osfd);
-			if (rv < 0)
-				_PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
-        } else {
-            rv = CloseHandle((HANDLE)osfd)?0:-1;
-			if (rv < 0)
-				_PR_MD_MAP_CLOSE_ERROR(GetLastError());
-		}
-
-        if (rv == 0 && me->io_suspended) {
-            if (me->io_fd == osfd) {
-                PRBool fWait;
-
-                _PR_THREAD_LOCK(me);
-                me->state = _PR_IO_WAIT;
-                /* The IO could have completed on another thread just after
-                 * calling closesocket while the io_suspended flag was true.  
-                 * So we now grab the lock to do a safe check on io_pending to
-                 * see if we need to wait or not.
-                 */
-                fWait = me->io_pending;
-                me->io_suspended = PR_FALSE;
-                me->md.interrupt_disabled = PR_TRUE;
-                _PR_THREAD_UNLOCK(me);
-
-                if (fWait)
-                    _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
-                PR_ASSERT(me->io_suspended ==  PR_FALSE);
-                PR_ASSERT(me->io_pending ==  PR_FALSE);
-				/*
-				 * I/O operation is no longer pending; the thread can now
-				 * run on any cpu
-				 */
-                _PR_THREAD_LOCK(me);
-                me->md.interrupt_disabled = PR_FALSE;
-				me->md.thr_bound_cpu = NULL;
-                me->io_suspended = PR_FALSE;
-                me->io_pending = PR_FALSE;
-                me->state = _PR_RUNNING;
-                _PR_THREAD_UNLOCK(me);
-            }
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (socket)  {
+        rv = closesocket((SOCKET)osfd);
+        if (rv < 0)
+            _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
+    } else {
+        rv = CloseHandle((HANDLE)osfd)?0:-1;
+        if (rv < 0)
+            _PR_MD_MAP_CLOSE_ERROR(GetLastError());
+    }
+
+    if (rv == 0 && me->io_suspended) {
+        if (me->io_fd == osfd) {
+            PRBool fWait;
+
+            _PR_THREAD_LOCK(me);
+            me->state = _PR_IO_WAIT;
+            /* The IO could have completed on another thread just after
+             * calling closesocket while the io_suspended flag was true.  
+             * So we now grab the lock to do a safe check on io_pending to
+             * see if we need to wait or not.
+             */
+            fWait = me->io_pending;
+            me->io_suspended = PR_FALSE;
+            me->md.interrupt_disabled = PR_TRUE;
+            _PR_THREAD_UNLOCK(me);
+
+            if (fWait)
+                _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+            PR_ASSERT(me->io_suspended ==  PR_FALSE);
+            PR_ASSERT(me->io_pending ==  PR_FALSE);
+            /*
+             * I/O operation is no longer pending; the thread can now
+             * run on any cpu
+             */
+            _PR_THREAD_LOCK(me);
+            me->md.interrupt_disabled = PR_FALSE;
+            me->md.thr_bound_cpu = NULL;
+            me->io_suspended = PR_FALSE;
+            me->io_pending = PR_FALSE;
+            me->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(me);
         }
-    } else { 
-        if (socket) {
-            rv = closesocket((SOCKET)osfd);
-			if (rv == -1)
-				_PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
-        } else {
-            rv = CloseHandle((HANDLE)osfd)?0:-1;
-			if (rv == -1)
-				_PR_MD_MAP_CLOSE_ERROR(GetLastError());
-		}
     }
     return rv;
 }
 
 PRStatus
 _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
 {
     BOOL rv;
@@ -2656,36 +2665,36 @@ PRStatus
         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
         return PR_FAILURE;
     }
     rv = SetHandleInformation(
             (HANDLE)fd->secret->md.osfd,
             HANDLE_FLAG_INHERIT,
             inheritable ? HANDLE_FLAG_INHERIT : 0);
     if (0 == rv) {
-        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
         return PR_FAILURE;
     }
     return PR_SUCCESS;
 } 
 
 
 /* --- DIR IO ------------------------------------------------------------ */
 #define GetFileFromDIR(d)       (d)->d_entry.cFileName
 #define FileIsHidden(d)       ((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
 
 void FlipSlashes(char *cp, int len)
 {
     while (--len >= 0) {
-    if (cp[0] == '/') {
-        cp[0] = PR_DIRECTORY_SEPARATOR;
+        if (cp[0] == '/') {
+            cp[0] = PR_DIRECTORY_SEPARATOR;
+        }
+        cp = _mbsinc(cp);
     }
-    cp++;
-    }
-}
+} /* end FlipSlashes() */
 
 /*
 **
 ** Local implementations of standard Unix RTL functions which are not provided
 ** by the VC RTL.
 **
 */
 
@@ -2974,17 +2983,17 @@ PRInt32
         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
         return -1;
     }
 
     /*
      * FindFirstFile() expands wildcard characters.  So
      * we make sure the pathname contains no wildcard.
      */
-    if (NULL != strpbrk(fn, "?*")) {
+    if (NULL != _mbspbrk(fn, "?*")) {
         PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
         return -1;
     }
 
     hFindFile = FindFirstFile(fn, &findFileData);
     if (INVALID_HANDLE_VALUE == hFindFile) {
         DWORD len;
         char *filePart;
@@ -2996,17 +3005,17 @@ PRInt32
          * root directory.  If not, and if the pathname ends in a slash,
          * we remove the final slash and try again.
          */
 
         /*
          * If the pathname does not contain ., \, and /, it cannot be
          * a root directory or a pathname that ends in a slash.
          */
-        if (NULL == strpbrk(fn, ".\\/")) {
+        if (NULL == _mbspbrk(fn, ".\\/")) {
             _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
             return -1;
         } 
         len = GetFullPathName(fn, sizeof(pathbuf), pathbuf,
                 &filePart);
         PR_ASSERT(0 != len);
         if (len > sizeof(pathbuf)) {
             PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
@@ -3172,16 +3181,44 @@ PRInt32
         return 0;
     } else {
         _PR_MD_MAP_MKDIR_ERROR(GetLastError());
         return -1;
     }
 }
 
 PRInt32
+_PR_MD_MAKE_DIR(const char *name, PRIntn mode)
+{
+    BOOL rv;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable,
+            &pSD, &pACL) == PR_SUCCESS) {
+        sa.nLength = sizeof(sa);
+        sa.lpSecurityDescriptor = pSD;
+        sa.bInheritHandle = FALSE;
+        lpSA = &sa;
+    }
+    rv = CreateDirectory(name, lpSA);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (rv) {
+        return 0;
+    } else {
+        _PR_MD_MAP_MKDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
 _PR_MD_RMDIR(const char *name)
 {
     if (RemoveDirectory(name)) {
         return 0;
     } else {
         _PR_MD_MAP_RMDIR_ERROR(GetLastError());
         return -1;
     }
@@ -3663,21 +3700,16 @@ PRInt32 IsFileLocal(HANDLE hFile)
       dwIndex++;
       dwMask = dwMask >> 1;
    }
 
    return _PR_REMOTE_FILE;
 }
 #endif /* _NEED_351_FILE_LOCKING_HACK */
 
-PR_IMPLEMENT(void) PR_NT_UseNonblock()
-{
-    _nt_use_async = 0;
-}
-
 PR_IMPLEMENT(PRStatus) PR_NT_CancelIo(PRFileDesc *fd)
 {
     PRThread *me = _PR_MD_CURRENT_THREAD();
 	PRBool fWait;
 	PRFileDesc *bottom;
 
 	bottom = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER);
     if (!me->io_suspended || (NULL == bottom) ||
new file mode 100644
--- /dev/null
+++ b/pr/src/md/windows/ntsec.c
@@ -0,0 +1,252 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#include "primpl.h"
+
+/*
+ * ntsec.c
+ *
+ * Implement the POSIX-style mode bits (access permissions) for
+ * files and other securable objects in Windows NT using Windows
+ * NT's security descriptors with appropriate discretionary
+ * access-control lists.
+ */
+
+/*
+ * The security identifiers (SIDs) for owner, primary group,
+ * and the Everyone (World) group.
+ *
+ * These SIDs are looked up during NSPR initialization and
+ * saved in this global structure (see _PR_NT_InitSids) so
+ * that _PR_NT_MakeSecurityDescriptorACL doesn't need to
+ * look them up every time.
+ */
+static struct {
+    PSID owner;
+    PSID group;
+    PSID everyone;
+} _pr_nt_sids;
+
+/*
+ * Initialize the SIDs for owner, primary group, and the Everyone
+ * group in the _pr_nt_sids structure.
+ *
+ * This function needs to be called by NSPR initialization.
+ */
+void _PR_NT_InitSids(void)
+{
+    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
+    HANDLE hToken;
+    UCHAR infoBuffer[1024];
+    PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) infoBuffer;
+    PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup
+            = (PTOKEN_PRIMARY_GROUP) infoBuffer;
+    DWORD dwLength;
+    BOOL rv;
+
+    /* Create a well-known SID for the Everyone group. */
+    if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
+            SECURITY_WORLD_RID,
+            0, 0, 0, 0, 0, 0, 0,
+            &_pr_nt_sids.everyone)) {
+        /*
+         * On non-NT systems, this function is not implemented,
+         * and neither are the other security functions. There
+         * is no point in going further.
+         */
+        PR_ASSERT(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED);
+        return;
+    }
+
+    /*
+     * Look up and make a copy of the owner and primary group
+     * SIDs in the access token of the calling process.
+     */
+    rv = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
+    PR_ASSERT(rv != 0);
+
+    rv = GetTokenInformation(hToken, TokenOwner, infoBuffer,
+            sizeof(infoBuffer), &dwLength);
+    PR_ASSERT(rv != 0);
+    dwLength = GetLengthSid(pTokenOwner->Owner);
+    _pr_nt_sids.owner = (PSID) PR_Malloc(dwLength);
+    PR_ASSERT(_pr_nt_sids.owner != NULL);
+    rv = CopySid(dwLength, _pr_nt_sids.owner, pTokenOwner->Owner);
+    PR_ASSERT(rv != 0);
+
+    rv = GetTokenInformation(hToken, TokenPrimaryGroup, infoBuffer,
+            sizeof(infoBuffer), &dwLength);
+    PR_ASSERT(rv != 0);
+    dwLength = GetLengthSid(pTokenPrimaryGroup->PrimaryGroup);
+    _pr_nt_sids.group = (PSID) PR_Malloc(dwLength);
+    PR_ASSERT(_pr_nt_sids.group != NULL);
+    rv = CopySid(dwLength, _pr_nt_sids.group,
+            pTokenPrimaryGroup->PrimaryGroup);
+    PR_ASSERT(rv != 0);
+
+    rv = CloseHandle(hToken);
+    PR_ASSERT(rv != 0);
+}
+
+/*
+ * Free the SIDs for owner, primary group, and the Everyone group
+ * in the _pr_nt_sids structure.
+ *
+ * This function needs to be called by NSPR cleanup.
+ */
+void
+_PR_NT_FreeSids(void)
+{
+    if (_pr_nt_sids.owner) {
+        PR_Free(_pr_nt_sids.owner);
+    }
+    if (_pr_nt_sids.group) {
+        PR_Free(_pr_nt_sids.group);
+    }
+    if (_pr_nt_sids.everyone) {
+        FreeSid(_pr_nt_sids.everyone);
+    }
+}
+
+/*
+ * Construct a security descriptor whose discretionary access-control
+ * list implements the specified mode bits.  The SIDs for owner, group,
+ * and everyone are obtained from the global _pr_nt_sids structure.
+ * Both the security descriptor and access-control list are returned
+ * and should be freed by a _PR_NT_FreeSecurityDescriptorACL call.
+ *
+ * The accessTable array maps NSPR's read, write, and execute access
+ * rights to the corresponding NT access rights for the securable
+ * object.
+ */
+PRStatus
+_PR_NT_MakeSecurityDescriptorACL(
+    PRIntn mode,
+    DWORD accessTable[],
+    PSECURITY_DESCRIPTOR *resultSD,
+    PACL *resultACL)
+{
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+    DWORD cbACL;  /* size of ACL */
+    DWORD accessMask;
+
+    if (_pr_nt_sids.owner == NULL) {
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    pSD = (PSECURITY_DESCRIPTOR) PR_Malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
+    if (pSD == NULL) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!SetSecurityDescriptorOwner(pSD, _pr_nt_sids.owner, FALSE)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!SetSecurityDescriptorGroup(pSD, _pr_nt_sids.group, FALSE)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+
+    /*
+     * Construct a discretionary access-control list with three
+     * access-control entries, one each for owner, primary group,
+     * and Everyone.
+     */
+
+    cbACL = sizeof(ACL)
+          + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))
+          + GetLengthSid(_pr_nt_sids.owner)
+          + GetLengthSid(_pr_nt_sids.group)
+          + GetLengthSid(_pr_nt_sids.everyone);
+    pACL = (PACL) PR_Malloc(cbACL);
+    if (pACL == NULL) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    accessMask = 0;
+    if (mode & 00400) accessMask |= accessTable[0];
+    if (mode & 00200) accessMask |= accessTable[1];
+    if (mode & 00100) accessMask |= accessTable[2];
+    if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+            _pr_nt_sids.owner)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    accessMask = 0;
+    if (mode & 00040) accessMask |= accessTable[0];
+    if (mode & 00020) accessMask |= accessTable[1];
+    if (mode & 00010) accessMask |= accessTable[2];
+    if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+            _pr_nt_sids.group)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    accessMask = 0;
+    if (mode & 00004) accessMask |= accessTable[0];
+    if (mode & 00002) accessMask |= accessTable[1];
+    if (mode & 00001) accessMask |= accessTable[2];
+    if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+            _pr_nt_sids.everyone)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+
+    if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+
+    *resultSD = pSD;
+    *resultACL = pACL;
+    return PR_SUCCESS;
+
+failed:
+    if (pSD) {
+        PR_Free(pSD);
+    }
+    if (pACL) {
+        PR_Free(pACL);
+    }
+    return PR_FAILURE;
+}
+
+/*
+ * Free the specified security descriptor and access-control list
+ * previously created by _PR_NT_MakeSecurityDescriptorACL.
+ */
+void
+_PR_NT_FreeSecurityDescriptorACL(PSECURITY_DESCRIPTOR pSD, PACL pACL)
+{
+    if (pSD) {
+        PR_Free(pSD);
+    }
+    if (pACL) {
+        PR_Free(pACL);
+    }
+}
--- a/pr/src/md/windows/ntthread.c
+++ b/pr/src/md/windows/ntthread.c
@@ -113,16 +113,18 @@ void
         _pr_currentCPUIndex = TlsAlloc();
         _pr_intsOffIndex = TlsAlloc();
         _pr_io_restartedIOIndex = TlsAlloc();
     }
 }
 
 void _PR_MD_CLEANUP_BEFORE_EXIT(void)
 {
+    _PR_NT_FreeSids();
+
     WSACleanup();
 
     if (!_pr_use_static_tls) {
         TlsFree(_pr_currentFiberIndex);
         TlsFree(_pr_lastFiberIndex);
         TlsFree(_pr_currentCPUIndex);
         TlsFree(_pr_intsOffIndex);
         TlsFree(_pr_io_restartedIOIndex);
--- a/pr/src/md/windows/w32ipcsem.c
+++ b/pr/src/md/windows/w32ipcsem.c
@@ -18,16 +18,32 @@
 
 /*
  * File: w32ipcsem.c
  * Description: implements named semaphores for NT and WIN95.
  */
 
 #include "primpl.h"
 
+/*
+ * NSPR-to-NT access right mapping table for semaphore objects.
+ *
+ * The SYNCHRONIZE access is required by WaitForSingleObject.
+ * The SEMAPHORE_MODIFY_STATE access is required by ReleaseSemaphore.
+ * The OR of these three access masks must equal SEMAPHORE_ALL_ACCESS.
+ * This is because if a semaphore object with the specified name
+ * exists, CreateSemaphore requests SEMAPHORE_ALL_ACCESS access to
+ * the existing object.
+ */
+static DWORD semAccessTable[] = {
+    STANDARD_RIGHTS_REQUIRED|0x1, /* read (0x1 is "query state") */
+    STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, /* write */
+    0 /* execute */
+};
+
 #ifndef _PR_GLOBAL_THREADS_ONLY
 
 /*
  * A fiber cannot call WaitForSingleObject because that
  * will block the other fibers running on the same thread.
  * If a fiber needs to wait on a (semaphore) handle, we
  * create a native thread to call WaitForSingleObject and
  * have the fiber join the native thread.
@@ -89,37 +105,52 @@ static DWORD FiberSafeWaitForSingleObjec
 }
 
 #endif /* !_PR_GLOBAL_THREADS_ONLY */
 
 PRSem *_PR_MD_OPEN_SEMAPHORE(
     const char *osname, PRIntn flags, PRIntn mode, PRUintn value)
 {
     PRSem *sem;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
 
     sem = PR_NEW(PRSem);
     if (sem == NULL) {
         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
         return NULL;
     }
     if (flags & PR_SEM_CREATE) {
-        sem->sem = CreateSemaphore(NULL, value, 0x7fffffff, osname);
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, semAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+        sem->sem = CreateSemaphore(lpSA, value, 0x7fffffff, osname);
+        if (lpSA != NULL) {
+            _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+        }
         if (sem->sem == NULL) {
             _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
             PR_DELETE(sem);
             return NULL;
         }
         if ((flags & PR_SEM_EXCL) && (GetLastError() == ERROR_ALREADY_EXISTS)) {
             PR_SetError(PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS);
             CloseHandle(sem->sem);
             PR_DELETE(sem);
             return NULL;
         }
     } else {
-        sem->sem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, osname);
+        sem->sem = OpenSemaphore(
+                SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, FALSE, osname);
         if (sem->sem == NULL) {
             DWORD err = GetLastError();
 
             /*
              * If we open a nonexistent named semaphore, NT
              * returns ERROR_FILE_NOT_FOUND, while Win95
              * returns ERROR_INVALID_NAME
              */
--- a/pr/src/md/windows/w32shm.c
+++ b/pr/src/md/windows/w32shm.c
@@ -21,28 +21,46 @@
 #include <prshm.h>
 #include <prerr.h>
 #include <prmem.h>
 
 #if defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)
 
 extern PRLogModuleInfo *_pr_shm_lm;
 
+/*
+ * NSPR-to-NT access right mapping table for file-mapping objects.
+ *
+ * The OR of these three access masks must equal FILE_MAP_ALL_ACCESS.
+ * This is because if a file-mapping object with the specified name
+ * exists, CreateFileMapping requests full access to the existing
+ * object.
+ */
+static DWORD filemapAccessTable[] = {
+    FILE_MAP_ALL_ACCESS & ~FILE_MAP_WRITE, /* read */
+    FILE_MAP_ALL_ACCESS & ~FILE_MAP_READ, /* write */ 
+    0  /* execute */
+};
+
 extern PRSharedMemory * _MD_OpenSharedMemory( 
         const char *name,
         PRSize      size,
         PRIntn      flags,
         PRIntn      mode
 )
 {
     char        ipcname[PR_IPC_NAME_SIZE];
     PRStatus    rc = PR_SUCCESS;
     DWORD dwHi, dwLo;
     PRSharedMemory *shm;
     DWORD flProtect = ( PAGE_READWRITE );
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
 
     rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
     if ( PR_FAILURE == rc )
     {
         PR_SetError(PR_UNKNOWN_ERROR, 0 );
         PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: name is invalid")); 
         return(NULL);
     }
@@ -67,33 +85,43 @@ extern PRSharedMemory * _MD_OpenSharedMe
     /* copy args to struct */
     strcpy( shm->ipcname, ipcname );
     shm->size = size; 
     shm->mode = mode;
     shm->flags = flags;
     shm->ident = _PR_SHM_IDENT;
 
     if (flags & PR_SHM_CREATE ) {
-        /* XXX: Not 64bit safe. Fix when WinNT goes 64bit, if ever */
+        /* XXX: Not 64bit safe. Fix when WinNT goes 64bit. */
         dwHi = 0;
         dwLo = shm->size;
 
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
         shm->handle = CreateFileMapping(
             (HANDLE)-1 ,
-            NULL,
+            lpSA,
             flProtect,
             dwHi,
             dwLo,
             shm->ipcname);
+        if (lpSA != NULL) {
+            _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+        }
 
         if ( NULL == shm->handle ) {
             PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
                 ( "PR_OpenSharedMemory: CreateFileMapping() failed: %s",
                     shm->ipcname )); 
-            PR_SetError( PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS );
+            _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
             PR_FREEIF( shm->ipcname )
             PR_DELETE( shm );
             return(NULL);
         } else {
             if (( flags & PR_SHM_EXCL) && ( GetLastError() == ERROR_ALREADY_EXISTS ))  {
                 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
                     ( "PR_OpenSharedMemory: Request exclusive & already exists",
                         shm->ipcname )); 
@@ -105,17 +133,17 @@ extern PRSharedMemory * _MD_OpenSharedMe
             } else {
                 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
                     ( "PR_OpenSharedMemory: CreateFileMapping() success: %s, handle: %d",
                         shm->ipcname, shm->handle ));
                 return(shm);
             }
         }
     } else {
-        shm->handle = OpenFileMapping( FILE_MAP_ALL_ACCESS, TRUE, shm->ipcname );
+        shm->handle = OpenFileMapping( FILE_MAP_WRITE, TRUE, shm->ipcname );
         if ( NULL == shm->handle ) {
             _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
             PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
                 ( "PR_OpenSharedMemory: OpenFileMapping() failed: %s, error: %d",
                     shm->ipcname, PR_GetOSError())); 
             PR_FREEIF( shm->ipcname );
             PR_DELETE( shm );
             return(NULL);
--- a/pr/src/md/windows/w95io.c
+++ b/pr/src/md/windows/w95io.c
@@ -19,20 +19,40 @@
 /* Windows 95 IO module
  *
  * Assumes synchronous I/O.
  *
  */
 
 #include "primpl.h"
 #include <direct.h>
+#include <mbstring.h>
+
 
 struct _MDLock               _pr_ioq_lock;
 
 /*
+ * NSPR-to-NT access right mapping table for files.
+ */
+static DWORD fileAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
+ * NSPR-to-NT access right mapping table for directories.
+ */
+static DWORD dirAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE|FILE_DELETE_CHILD,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
  * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
  * We store the value in a PRTime variable for convenience.
  * This constant is used by _PR_FileTimeToPRTime().
  */
 #if defined(__MINGW32__)
 static const PRTime _pr_filetime_offset = 116444736000000000LL;
 #else
 static const PRTime _pr_filetime_offset = 116444736000000000i64;
@@ -67,16 +87,18 @@ void
         systime.wSecond = 0;
         systime.wMilliseconds = 0;
 
         rv = SystemTimeToFileTime(&systime, &filetime.ft);
         PR_ASSERT(0 != rv);
         PR_ASSERT(filetime.prt == _pr_filetime_offset);
     }
 #endif /* DEBUG */
+
+    _PR_NT_InitSids();
 }
 
 PRStatus
 _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
 {
     DWORD rv;
 
     PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
@@ -177,16 +199,77 @@ PRInt32
 		_PR_MD_MAP_OPEN_ERROR(GetLastError());
         return -1; 
 	}
 
     return (PRInt32)file;
 }
 
 PRInt32
+_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, int mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (osflags & PR_CREATE_FILE) {
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+    }
+    
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+ 
+    if (osflags & PR_RDONLY || osflags & PR_RDWR)
+        access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR)
+        access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE) {
+        if (osflags & PR_TRUNCATE)
+            flags = CREATE_ALWAYS;
+        else
+            flags = OPEN_ALWAYS;
+    } else {
+        if (osflags & PR_TRUNCATE)
+            flags = TRUNCATE_EXISTING;
+        else
+            flags = OPEN_EXISTING;
+    }
+
+    file = CreateFile(name,
+                      access,
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      lpSA,
+                      flags,
+                      flag6,
+                      NULL);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (file == INVALID_HANDLE_VALUE) {
+		_PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1; 
+	}
+
+    return (PRInt32)file;
+}
+
+PRInt32
 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
 {
     PRUint32 bytes;
     int rv, err;
 
     rv = ReadFile((HANDLE)fd->secret->md.osfd,
             (LPVOID)buf,
             len,
@@ -348,22 +431,23 @@ PRInt32
 
 /* --- DIR IO ------------------------------------------------------------ */
 #define GetFileFromDIR(d)       (d)->d_entry.cFileName
 #define FileIsHidden(d)	((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
 
 void FlipSlashes(char *cp, int len)
 {
     while (--len >= 0) {
-    if (cp[0] == '/') {
-        cp[0] = PR_DIRECTORY_SEPARATOR;
+        if (cp[0] == '/') {
+            cp[0] = PR_DIRECTORY_SEPARATOR;
+        }
+        cp = _mbsinc(cp);
     }
-    cp++;
-    }
-}
+} /* end FlipSlashes() */
+
 
 /*
 **
 ** Local implementations of standard Unix RTL functions which are not provided
 ** by the VC RTL.
 **
 */
 
@@ -656,17 +740,17 @@ PRInt32
         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
         return -1;
     }
 
     /*
      * FindFirstFile() expands wildcard characters.  So
      * we make sure the pathname contains no wildcard.
      */
-    if (NULL != strpbrk(fn, "?*")) {
+    if (NULL != _mbspbrk(fn, "?*")) {
         PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
         return -1;
     }
 
     hFindFile = FindFirstFile(fn, &findFileData);
     if (INVALID_HANDLE_VALUE == hFindFile) {
         DWORD len;
         char *filePart;
@@ -678,17 +762,17 @@ PRInt32
          * root directory.  If not, and if the pathname ends in a slash,
          * we remove the final slash and try again.
          */
 
         /*
          * If the pathname does not contain ., \, and /, it cannot be
          * a root directory or a pathname that ends in a slash.
          */
-        if (NULL == strpbrk(fn, ".\\/")) {
+        if (NULL == _mbspbrk(fn, ".\\/")) {
             _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
             return -1;
         } 
         len = GetFullPathName(fn, sizeof(pathbuf), pathbuf,
                 &filePart);
         PR_ASSERT(0 != len);
         if (len > sizeof(pathbuf)) {
             PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
@@ -861,16 +945,44 @@ PRInt32
         return 0;
     } else {
 		_PR_MD_MAP_MKDIR_ERROR(GetLastError());
         return -1;
     }
 }
 
 PRInt32
+_PR_MD_MAKE_DIR(const char *name, PRIntn mode)
+{
+    BOOL rv;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable,
+            &pSD, &pACL) == PR_SUCCESS) {
+        sa.nLength = sizeof(sa);
+        sa.lpSecurityDescriptor = pSD;
+        sa.bInheritHandle = FALSE;
+        lpSA = &sa;
+    }
+    rv = CreateDirectory(name, lpSA);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (rv) {
+        return 0;
+    } else {
+        _PR_MD_MAP_MKDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
 _PR_MD_RMDIR(const char *name)
 {
     if (RemoveDirectory(name)) {
         return 0;
     } else {
 		_PR_MD_MAP_RMDIR_ERROR(GetLastError());
         return -1;
     }
--- a/pr/src/md/windows/w95thred.c
+++ b/pr/src/md/windows/w95thred.c
@@ -43,16 +43,18 @@ void
     _pr_currentThreadIndex = TlsAlloc();
     _pr_lastThreadIndex = TlsAlloc();
     _pr_currentCPUIndex = TlsAlloc();
 #endif
 }
 
 void _PR_MD_CLEANUP_BEFORE_EXIT(void)
 {
+    _PR_NT_FreeSids();
+
     WSACleanup();
 
 #ifndef _PR_USE_STATIC_TLS
     TlsFree(_pr_currentThreadIndex);
     TlsFree(_pr_lastThreadIndex);
     TlsFree(_pr_currentCPUIndex);
 #endif
 }
--- a/pr/src/md/windows/win32_errors.c
+++ b/pr/src/md/windows/win32_errors.c
@@ -137,16 +137,19 @@ void _MD_win32_map_default_error(PRInt32
             prError = PR_NO_MORE_FILES_ERROR;
             break;
         case ERROR_OPEN_FAILED:
             prError = PR_IO_ERROR;
             break;
         case ERROR_OPEN_FILES:
             prError = PR_IO_ERROR;
             break;
+        case ERROR_OPERATION_ABORTED:
+            prError = PR_OPERATION_ABORTED_ERROR;
+            break;
         case ERROR_OUTOFMEMORY:
             prError = PR_INSUFFICIENT_RESOURCES_ERROR;
             break;
         case ERROR_PATH_BUSY:
             prError = PR_IO_ERROR;
             break;
         case ERROR_PATH_NOT_FOUND:
             prError = PR_FILE_NOT_FOUND_ERROR;
--- a/pr/src/misc/prerr.c
+++ b/pr/src/misc/prerr.c
@@ -83,17 +83,17 @@ static const struct PRErrorMessage text[
 	{"PR_FILE_EXISTS_ERROR",    "Cannot create or rename a filename that already exists"},
 	{"PR_MAX_DIRECTORY_ENTRIES_ERROR",    "Directory is full.  No additional filenames may be added"},
 	{"PR_INVALID_DEVICE_STATE_ERROR",    "The required device was in an invalid state"},
 	{"PR_DEVICE_IS_LOCKED_ERROR",    "The device is locked"},
 	{"PR_NO_MORE_FILES_ERROR",    "No more entries in the directory"},
 	{"PR_END_OF_FILE_ERROR",    "Encountered end of file"},
 	{"PR_FILE_SEEK_ERROR",    "Seek error"},
 	{"PR_FILE_IS_BUSY_ERROR",    "The file is busy"},
-	{"PR_RESERVED_ERROR_5935",    "Reserved Error Code -5935"},
+	{"PR_OPERATION_ABORTED_ERROR",    "The I/O operation was aborted"},
 	{"PR_IN_PROGRESS_ERROR",    "Operation is still in progress (probably a non-blocking connect)"},
 	{"PR_ALREADY_INITIATED_ERROR",    "Operation has already been initiated (probably a non-blocking connect)"},
 	{"PR_GROUP_EMPTY_ERROR",    "The wait group is empty"},
 	{"PR_INVALID_STATE_ERROR",    "Object state improper for request"},
 	{"PR_NETWORK_DOWN_ERROR",    "Network is down"},
 	{"PR_SOCKET_SHUTDOWN_ERROR",    "Socket shutdown"},
 	{"PR_CONNECT_ABORTED_ERROR",    "Connection aborted"},
 	{"PR_HOST_UNREACHABLE_ERROR",    "Host is unreachable"},
--- a/pr/src/misc/prerr.et
+++ b/pr/src/misc/prerr.et
@@ -94,17 +94,17 @@ ec PR_MAX_DIRECTORY_ENTRIES_ERROR,
 "Directory is full.  No additional filenames may be added"
 ec PR_INVALID_DEVICE_STATE_ERROR,
 "The required device was in an invalid state"
 ec PR_DEVICE_IS_LOCKED_ERROR, "The device is locked"
 ec PR_NO_MORE_FILES_ERROR,      "No more entries in the directory"
 ec PR_END_OF_FILE_ERROR,        "Encountered end of file"
 ec PR_FILE_SEEK_ERROR,  "Seek error"
 ec PR_FILE_IS_BUSY_ERROR,       "The file is busy"
-ec PR_RESERVED_ERROR_5935,       "Reserved Error Code -5935"
+ec PR_OPERATION_ABORTED_ERROR,  "The I/O operation was aborted"
 ec PR_IN_PROGRESS_ERROR,
 "Operation is still in progress (probably a non-blocking connect)"
 ec PR_ALREADY_INITIATED_ERROR,
 "Operation has already been initiated (probably a non-blocking connect)"
 ec PR_GROUP_EMPTY_ERROR,        "The wait group is empty"
 ec PR_INVALID_STATE_ERROR,      "Object state improper for request"
 ec PR_NETWORK_DOWN_ERROR,       "Network is down"
 ec PR_SOCKET_SHUTDOWN_ERROR,    "Socket shutdown"
--- a/pr/src/misc/prerr.properties
+++ b/pr/src/misc/prerr.properties
@@ -77,17 +77,17 @@ PR_DIRECTORY_CORRUPTED_ERROR=The directo
 PR_FILE_EXISTS_ERROR=Cannot create or rename a filename that already exists
 PR_MAX_DIRECTORY_ENTRIES_ERROR=Directory is full.  No additional filenames may be added
 PR_INVALID_DEVICE_STATE_ERROR=The required device was in an invalid state
 PR_DEVICE_IS_LOCKED_ERROR=The device is locked
 PR_NO_MORE_FILES_ERROR=No more entries in the directory
 PR_END_OF_FILE_ERROR=Encountered end of file
 PR_FILE_SEEK_ERROR=Seek error
 PR_FILE_IS_BUSY_ERROR=The file is busy
-PR_RESERVED_ERROR_5935=Reserved Error Code -5935
+PR_OPERATION_ABORTED_ERROR=The I/O operation was aborted
 PR_IN_PROGRESS_ERROR=Operation is still in progress (probably a non-blocking connect)
 PR_ALREADY_INITIATED_ERROR=Operation has already been initiated (probably a non-blocking connect)
 PR_GROUP_EMPTY_ERROR=The wait group is empty
 PR_INVALID_STATE_ERROR=Object state improper for request
 PR_NETWORK_DOWN_ERROR=Network is down
 PR_SOCKET_SHUTDOWN_ERROR=Socket shutdown
 PR_CONNECT_ABORTED_ERROR=Connection aborted
 PR_HOST_UNREACHABLE_ERROR=Host is unreachable
--- a/pr/src/misc/prerror.c
+++ b/pr/src/misc/prerror.c
@@ -28,22 +28,16 @@ PR_IMPLEMENT(PRErrorCode) PR_GetError()
 }
 
 PR_IMPLEMENT(PRInt32) PR_GetOSError()
 {
     PRThread *thread = PR_GetCurrentThread();
     return thread->osErrorCode;
 }
 
-PR_IMPLEMENT(const char*) PR_GetErrorString()
-{
-    PRThread *thread = PR_GetCurrentThread();
-    return thread->errorString;
-}
-
 PR_IMPLEMENT(void) PR_SetError(PRErrorCode code, PRInt32 osErr)
 {
     PRThread *thread = PR_GetCurrentThread();
     thread->errorCode = code;
     thread->osErrorCode = osErr;
     thread->errorStringSize = 0;
     PR_DELETE(thread->errorString);
 }
--- a/pr/src/misc/prinit.c
+++ b/pr/src/misc/prinit.c
@@ -73,21 +73,21 @@ static void _PR_InitCallOnce(void);
 PRBool _pr_initialized = PR_FALSE;
 
 
 PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion)
 {
     /*
     ** This is the secret handshake algorithm.
     **
-    ** This release (3.1) is backward compatible with
-    ** all the previous releases ("2.1 19980529", "3.0",
-    ** "3.0.x").  It is not compatible with future
-    ** releases or patches.  So this release has a
-    ** simple version compatibility check algorithm.
+    ** This release has a simple version compatibility
+    ** check algorithm.  This release is not backward
+    ** compatible with previous major releases.  It is
+    ** not compatible with future major, minor, or
+    ** patch releases.
     */
     int vmajor = 0, vminor = 0, vpatch = 0;
     const char *ptr = importedVersion;
 
     while (isdigit(*ptr)) {
         vmajor = 10 * vmajor + *ptr - '0';
         ptr++;
     }
@@ -101,17 +101,17 @@ PR_IMPLEMENT(PRBool) PR_VersionCheck(con
             ptr++;
             while (isdigit(*ptr)) {
                 vpatch = 10 * vpatch + *ptr - '0';
                 ptr++;
             }
         }
     }
 
-    if (vmajor > PR_VMAJOR) {
+    if (vmajor != PR_VMAJOR) {
         return PR_FALSE;
     }
     if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) {
         return PR_FALSE;
     }
     if (vmajor == PR_VMAJOR && vminor == PR_VMINOR && vpatch > PR_VPATCH) {
         return PR_FALSE;
     }
@@ -139,16 +139,20 @@ static void _pr_SetNativeThreadsOnlyMode
     if (globalp) {
         _native_threads_only = (*globalp != PR_FALSE);
     } else if (envp = getenv("NSPR_NATIVE_THREADS_ONLY")) {
         _native_threads_only = (atoi(envp) == 1);
     }
 }
 #endif
 
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+extern PRStatus _pr_init_ipv6();
+#endif
+
 static void _PR_InitStuff(void)
 {
 
     if (_pr_initialized) return;
     _pr_initialized = PR_TRUE;
 #ifdef WINNT
     _pr_SetNativeThreadsOnlyMode();
 #endif
@@ -215,16 +219,20 @@ static void _PR_InitStuff(void)
     _PR_InitLinker();
     _PR_InitCallOnce();
     _PR_InitDtoa();
     _PR_InitMW();
     _PR_InitRWLocks();
 
     nspr_InitializePRErrorTable();
 
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+	_pr_init_ipv6();
+#endif
+	
     _PR_MD_FINAL_INIT();
 }
 
 void _PR_ImplicitInitialization()
 {
 	_PR_InitStuff();
 
     /* Enable interrupts */
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -90,23 +90,64 @@ static sigset_t timer_set;
 #define _PR_HAVE_GETPROTO_R
 #define _PR_HAVE_5_ARG_GETPROTO_R
 #endif
 
 #if !defined(_PR_HAVE_GETPROTO_R)
 PRLock* _getproto_lock = NULL;
 #endif
 
-#if defined(_PR_INET6)
-PRBool _pr_ipv6_enabled = PR_FALSE;
-#if defined(AIX)
-const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
-const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
-#endif /* AIX */
-#endif /* _PR_INET6 */
+#if defined(_PR_INET6_PROBE)
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+#endif
+
+#define _PR_IN6_IS_ADDR_UNSPECIFIED(a)				\
+				(((a)->pr_s6_addr32[0] == 0) &&	\
+				((a)->pr_s6_addr32[1] == 0) &&		\
+				((a)->pr_s6_addr32[2] == 0) &&		\
+				((a)->pr_s6_addr32[3] == 0))
+ 
+#define _PR_IN6_IS_ADDR_LOOPBACK(a)					\
+               (((a)->pr_s6_addr32[0] == 0)	&&	\
+               ((a)->pr_s6_addr32[1] == 0)		&&	\
+               ((a)->pr_s6_addr32[2] == 0)		&&	\
+               ((a)->pr_s6_addr[12] == 0)		&&	\
+               ((a)->pr_s6_addr[13] == 0)		&&	\
+               ((a)->pr_s6_addr[14] == 0)		&&	\
+               ((a)->pr_s6_addr[15] == 0x1U))
+ 
+const PRIPv6Addr _pr_in6addr_any =	{{{ 0, 0, 0, 0,
+										0, 0, 0, 0,
+										0, 0, 0, 0,
+										0, 0, 0, 0 }}};
+
+const PRIPv6Addr _pr_in6addr_loopback = {{{ 0, 0, 0, 0,
+											0, 0, 0, 0,
+											0, 0, 0, 0,
+											0, 0, 0, 0x1U }}};
+/*
+ * The values at bytes 10 and 11 are compared using pointers to
+ * 8-bit fields, and not 32-bit fields, to make the comparison work on
+ * both big-endian and little-endian systems
+ */
+
+#define _PR_IN6_IS_ADDR_V4MAPPED(a)			\
+		(((a)->pr_s6_addr32[0] == 0) 	&&	\
+		((a)->pr_s6_addr32[1] == 0)	&&	\
+		((a)->pr_s6_addr[8] == 0)		&&	\
+		((a)->pr_s6_addr[9] == 0)		&&	\
+		((a)->pr_s6_addr[10] == 0xff)	&&	\
+		((a)->pr_s6_addr[11] == 0xff))
+
+#define _PR_IN6_IS_ADDR_V4COMPAT(a)			\
+		(((a)->pr_s6_addr32[0] == 0) &&	\
+		((a)->pr_s6_addr32[1] == 0) &&		\
+		((a)->pr_s6_addr32[2] == 0))
+
+#define _PR_IN6_V4MAPPED_TO_IPADDR(a) ((a)->pr_s6_addr32[3])
 
 void _PR_InitNet(void)
 {
 #if defined(XP_UNIX)
 #ifdef HAVE_NETCONFIG
 	/*
 	 * This one-liner prevents the endless re-open's and re-read's of
 	 * /etc/netconfig on EACH and EVERY call to accept(), connect(), etc.
@@ -117,41 +158,16 @@ void _PR_InitNet(void)
 	sigaddset(&timer_set, SIGALRM);
 #endif
 #if !defined(_PR_NO_PREEMPT)
 	_pr_dnsLock = PR_NewLock();
 #endif
 #if !defined(_PR_HAVE_GETPROTO_R)
 	_getproto_lock = PR_NewLock();
 #endif
-
-}
-
-PR_IMPLEMENT(PRStatus) PR_SetIPv6Enable(PRBool itIs)
-{
-#if defined(XP_MAC)
-#pragma unused (itIs)
-#endif
-
-#if defined(_PR_INET6)
-    _pr_ipv6_enabled = itIs;
-    return PR_SUCCESS;
-#else /* defined(_PR_INET6) */
-    PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, 0);
-    return PR_FAILURE;
-#endif /* defined(_PR_INET6) */
-}  /* PR_SetIPv6Enable */
-
-PR_IMPLEMENT(PRStatus) PR_GetHostName(char *name, PRUint32 namelen)
-{
-#if defined(DEBUG)
-    static PRBool warn = PR_TRUE;
-    if (warn) warn = _PR_Obsolete("PR_GetHostName()", "PR_GetSystemInfo()");
-#endif
-    return PR_GetSystemInfo(PR_SI_HOSTNAME, name, namelen);
 }
 
 /*
 ** Allocate space from the buffer, aligning it to "align" before doing
 ** the allocation. "align" must be a power of 2.
 */
 static char *Alloc(PRIntn amount, char **bufp, PRIntn *buflenp, PRIntn align)
 {
@@ -169,134 +185,123 @@ static char *Alloc(PRIntn amount, char *
 	if (buflen < amount) {
 		return 0;
 	}
 	*bufp = buf + amount;
 	*buflenp = buflen - amount;
 	return buf;
 }
 
-#if defined(_PR_INET6)
-
 typedef enum _PRIPAddrConversion {
     _PRIPAddrNoConversion,
     _PRIPAddrIPv4Mapped,
     _PRIPAddrIPv4Compat
 } _PRIPAddrConversion;
 
 /*
 ** Convert an IPv4 address (v4) to an IPv4-mapped IPv6 address (v6).
 */
 static void MakeIPv4MappedAddr(const char *v4, char *v6)
 {
     memset(v6, 0, 10);
     memset(v6 + 10, 0xff, 2);
     memcpy(v6 + 12, v4, 4);
-    PR_ASSERT(IN6_IS_ADDR_V4MAPPED((struct in6_addr *) v6));
+    PR_ASSERT(_PR_IN6_IS_ADDR_V4MAPPED(((PRIPv6Addr *) v6)));
 }
 
 /*
 ** Convert an IPv4 address (v4) to an IPv4-compatible IPv6 address (v6).
 */
 static void MakeIPv4CompatAddr(const char *v4, char *v6)
 {
     memset(v6, 0, 12);
     memcpy(v6 + 12, v4, 4);
-    PR_ASSERT(IN6_IS_ADDR_V4COMPAT((struct in6_addr *) v6));
+    PR_ASSERT(_PR_IN6_IS_ADDR_V4COMPAT(((PRIPv6Addr *) v6)));
 }
 
-#endif /* _PR_INET6 */
-
 /*
 ** Copy a hostent, and all of the memory that it refers to into
 ** (hopefully) stacked buffers.
 */
 static PRStatus CopyHostent(
     struct hostent *from,
-    char *buf,
-    PRIntn bufsize,
-#if defined(_PR_INET6)
+    char **buf,
+    PRIntn *bufsize,
     _PRIPAddrConversion conversion,
-#endif
     PRHostEnt *to)
 {
 	PRIntn len, na;
 	char **ap;
 
-	/* Do the easy stuff */
-#if defined(_PR_INET6)
 	if (conversion != _PRIPAddrNoConversion
 			&& from->h_addrtype == AF_INET) {
 		PR_ASSERT(from->h_length == 4);
-		to->h_addrtype = AF_INET6;
+		to->h_addrtype = PR_AF_INET6;
 		to->h_length = 16;
 	} else {
-		to->h_addrtype = from->h_addrtype;
+#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+		if (AF_INET6 == from->h_addrtype)
+			to->h_addrtype = PR_AF_INET6;
+		else
+#endif
+			to->h_addrtype = from->h_addrtype;
 		to->h_length = from->h_length;
 	}
-#else
-	to->h_addrtype = from->h_addrtype;
-	to->h_length = from->h_length;
-#endif
 
 	/* Copy the official name */
 	if (!from->h_name) return PR_FAILURE;
 	len = strlen(from->h_name) + 1;
-	to->h_name = Alloc(len, &buf, &bufsize, 0);
+	to->h_name = Alloc(len, buf, bufsize, 0);
 	if (!to->h_name) return PR_FAILURE;
 	memcpy(to->h_name, from->h_name, len);
 
 	/* Count the aliases, then allocate storage for the pointers */
 	if (!from->h_aliases) {
 		na = 1;
 	} else {
 		for (na = 1, ap = from->h_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */
 	}
 	to->h_aliases = (char**)Alloc(
-	    na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+	    na * sizeof(char*), buf, bufsize, sizeof(char**));
 	if (!to->h_aliases) return PR_FAILURE;
 
 	/* Copy the aliases, one at a time */
 	if (!from->h_aliases) {
 		to->h_aliases[0] = 0;
 	} else {
 		for (na = 0, ap = from->h_aliases; *ap != 0; na++, ap++) {
 			len = strlen(*ap) + 1;
-			to->h_aliases[na] = Alloc(len, &buf, &bufsize, 0);
+			to->h_aliases[na] = Alloc(len, buf, bufsize, 0);
 			if (!to->h_aliases[na]) return PR_FAILURE;
 			memcpy(to->h_aliases[na], *ap, len);
 		}
 		to->h_aliases[na] = 0;
 	}
 
 	/* Count the addresses, then allocate storage for the pointers */
 	for (na = 1, ap = from->h_addr_list; *ap != 0; na++, ap++){;} /* nothing to execute */
 	to->h_addr_list = (char**)Alloc(
-	    na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+	    na * sizeof(char*), buf, bufsize, sizeof(char**));
 	if (!to->h_addr_list) return PR_FAILURE;
 
 	/* Copy the addresses, one at a time */
 	for (na = 0, ap = from->h_addr_list; *ap != 0; na++, ap++) {
-		to->h_addr_list[na] = Alloc(to->h_length, &buf, &bufsize, 0);
+		to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0);
 		if (!to->h_addr_list[na]) return PR_FAILURE;
-#if defined(_PR_INET6)
 		if (conversion != _PRIPAddrNoConversion
 				&& from->h_addrtype == AF_INET) {
 			if (conversion == _PRIPAddrIPv4Mapped) {
 				MakeIPv4MappedAddr(*ap, to->h_addr_list[na]);
 			} else {
 				PR_ASSERT(conversion == _PRIPAddrIPv4Compat);
 				MakeIPv4CompatAddr(*ap, to->h_addr_list[na]);
 			}
 		} else {
 			memcpy(to->h_addr_list[na], *ap, to->h_length);
 		}
-#else
-		memcpy(to->h_addr_list[na], *ap, to->h_length);
-#endif
 	}
 	to->h_addr_list[na] = 0;
 	return PR_SUCCESS;
 }
 
 #if !defined(_PR_HAVE_GETPROTO_R)
 /*
 ** Copy a protoent, and all of the memory that it refers to into
@@ -340,260 +345,325 @@ static PRStatus CopyProtoent(
 PR_IMPLEMENT(PRStatus) PR_GetHostByName(
     const char *name, char *buf, PRIntn bufsize, PRHostEnt *hp)
 {
 	struct hostent *h;
 	PRStatus rv = PR_FAILURE;
 #ifdef XP_UNIX
 	sigset_t oldset;
 #endif
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
-	int error_num;
-#endif
 
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
 #ifdef XP_UNIX
 	DISABLECLOCK(&oldset);
 #endif
 	LOCK_DNS();
 
-#ifdef _PR_INET6
-    if (_pr_ipv6_enabled)
-    {
-#ifdef _PR_HAVE_GETHOSTBYNAME2
-        h = gethostbyname2(name, AF_INET6);
-        if (NULL == h)
-        {
-            h = gethostbyname2(name, AF_INET);
-        }
-#elif defined(_PR_HAVE_GETIPNODEBYNAME)
-        h = getipnodebyname(name, AF_INET6, AI_DEFAULT, &error_num);
-#else
-#error "Unknown name-to-address translation function"
-#endif
-    }
-    else
-    {
-#ifdef XP_OS2_VACPP
-	    h = gethostbyname((char *)name);
-#else
-        h = gethostbyname(name);
-#endif
-    }
-#else
 #ifdef XP_OS2_VACPP
 	h = gethostbyname((char *)name);
 #else
     h = gethostbyname(name);
 #endif
-#endif /* _PR_INET6 */
     
 	if (NULL == h)
 	{
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
-	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
-#else
 	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
-#endif
 	}
 	else
 	{
-#if defined(_PR_INET6)
 		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
-
-		if (_pr_ipv6_enabled) conversion = _PRIPAddrIPv4Mapped;
-		rv = CopyHostent(h, buf, bufsize, conversion, hp);
-#else
-		rv = CopyHostent(h, buf, bufsize, hp);
-#endif
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
 		if (PR_SUCCESS != rv)
 		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
-		freehostent(h);
-#endif
 	}
 	UNLOCK_DNS();
 #ifdef XP_UNIX
 	ENABLECLOCK(&oldset);
 #endif
 	return rv;
 }
 
+#if defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+typedef struct hostent  * (*_pr_getipnodebyname_t)(const char *, int,
+										int, int *);
+typedef struct hostent  * (*_pr_getipnodebyaddr_t)(const void *, size_t,
+													int, int *);
+typedef void (*_pr_freehostent_t)(struct hostent *);
+extern void * _pr_getipnodebyname_fp;
+extern void * _pr_getipnodebyaddr_fp;
+extern void * _pr_freehostent_fp;
+#endif
+
 PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
     const char *name, PRUint16 af, PRIntn flags,
     char *buf, PRIntn bufsize, PRHostEnt *hp)
 {
-	struct hostent *h;
+	struct hostent *h = 0;
 	PRStatus rv = PR_FAILURE;
 #ifdef XP_UNIX
 	sigset_t oldset;
 #endif
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+	PRUint16 md_af = af;
 	int error_num;
+	int tmp_flags = 0;
+#endif
+#if defined(_PR_HAVE_GETHOSTBYNAME2)
+    PRBool did_af_inet = PR_FALSE;
+    char **new_addr_list;
 #endif
 
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
-#if defined(_PR_INET6)
-    PR_ASSERT(af == AF_INET || af == AF_INET6);
-    if (af != AF_INET && af != AF_INET6) {
-        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-        return PR_FAILURE;
-    }
-#else
-    PR_ASSERT(af == AF_INET);
-    if (af != AF_INET) {
-        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-        return PR_FAILURE;
-    }
-#endif
-
-    /*
-     * Flags other than PR_AI_DEFAULT are not yet supported.
-     */
-    PR_ASSERT(flags == PR_AI_DEFAULT);
-    if (flags != PR_AI_DEFAULT) {
+    PR_ASSERT(af == PR_AF_INET || af == PR_AF_INET6);
+    if (af != PR_AF_INET && af != PR_AF_INET6) {
         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
         return PR_FAILURE;
     }
 
 #ifdef XP_UNIX
 	DISABLECLOCK(&oldset);
 #endif
 	LOCK_DNS();
 
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+	if (flags & PR_AI_V4MAPPED)
+		tmp_flags |= AI_V4MAPPED;
+	if (flags & PR_AI_ADDRCONFIG)
+		tmp_flags |= AI_ADDRCONFIG;
+	if (flags & PR_AI_ALL)
+		tmp_flags |= AI_ALL;
+    if (af == PR_AF_INET6)
+    	md_af = AF_INET6;
+	else
+    	md_af = af;
+#endif
+
 #ifdef _PR_INET6
 #ifdef _PR_HAVE_GETHOSTBYNAME2
-    if (af == AF_INET6)
+    if (af == PR_AF_INET6)
     {
-        h = gethostbyname2(name, af); 
-        if (NULL == h)
+#ifdef _PR_INET6_PROBE
+      if (_pr_ipv6_is_present == PR_TRUE)
+#endif
+        h = gethostbyname2(name, AF_INET6); 
+        if ((NULL == h) && (flags & PR_AI_V4MAPPED))
         {
+            did_af_inet = PR_TRUE;
             h = gethostbyname2(name, AF_INET);
         }
     }
     else
     {
+        did_af_inet = PR_TRUE;
         h = gethostbyname2(name, af);
     }
 #elif defined(_PR_HAVE_GETIPNODEBYNAME)
-    h = getipnodebyname(name, af, AI_DEFAULT, &error_num);
+    h = getipnodebyname(name, md_af, tmp_flags, &error_num);
 #else
 #error "Unknown name-to-address translation function"
-#endif
+#endif	/* _PR_HAVE_GETHOSTBYNAME2 */
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    if (_pr_ipv6_is_present == PR_TRUE)
+    	h = (*((_pr_getipnodebyname_t)_pr_getipnodebyname_fp))(name, md_af, tmp_flags, &error_num);
+	else
+    	h = gethostbyname(name);
 #else /* _PR_INET6 */
 #ifdef XP_OS2_VACPP
 	h = gethostbyname((char *)name);
 #else
     h = gethostbyname(name);
 #endif
 #endif /* _PR_INET6 */
     
 	if (NULL == h)
 	{
 #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
 	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+		else
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 #else
 	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 #endif
 	}
 	else
 	{
-#if defined(_PR_INET6)
 		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
 
-		if (af == AF_INET6) conversion = _PRIPAddrIPv4Mapped;
-		rv = CopyHostent(h, buf, bufsize, conversion, hp);
-#else
-		rv = CopyHostent(h, buf, bufsize, hp);
-#endif
+		if (af == PR_AF_INET6) conversion = _PRIPAddrIPv4Mapped;
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
 		if (PR_SUCCESS != rv)
 		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
 #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
 		freehostent(h);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+			(*((_pr_freehostent_t)_pr_freehostent_fp))(h);
+#endif
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+		if ((flags & PR_AI_V4MAPPED) && (flags & (PR_AI_ALL|PR_AI_ADDRCONFIG))
+				&& !did_af_inet && (h = gethostbyname2(name, AF_INET)) != 0) {
+			/* Append the V4 addresses to the end of the list */
+			PRIntn na, na_old;
+			char **ap;
+			
+			/* Count the addresses, then grow storage for the pointers */
+			for (na_old = 0, ap = hp->h_addr_list; *ap != 0; na_old++, ap++)
+					{;} /* nothing to execute */
+			for (na = na_old + 1, ap = h->h_addr_list; *ap != 0; na++, ap++)
+					{;} /* nothing to execute */
+			new_addr_list = (char**)Alloc(
+				na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+			if (!new_addr_list) return PR_FAILURE;
+
+			/* Copy the V6 addresses, one at a time */
+			for (na = 0, ap = hp->h_addr_list; *ap != 0; na++, ap++) {
+				new_addr_list[na] = hp->h_addr_list[na];
+			}
+			hp->h_addr_list = new_addr_list;
+
+			/* Copy the V4 addresses, one at a time */
+			for (ap = h->h_addr_list; *ap != 0; na++, ap++) {
+				hp->h_addr_list[na] = Alloc(hp->h_length, &buf, &bufsize, 0);
+				if (!hp->h_addr_list[na]) return PR_FAILURE;
+				MakeIPv4MappedAddr(*ap, hp->h_addr_list[na]);
+			}
+			hp->h_addr_list[na] = 0;
+		}
 #endif
 	}
+
 	UNLOCK_DNS();
 #ifdef XP_UNIX
 	ENABLECLOCK(&oldset);
 #endif
 	return rv;
 }
 
 PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
     const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry)
 {
 	struct hostent *h;
 	PRStatus rv = PR_FAILURE;
 	const void *addr;
+	PRUint32 tmp_ip;
 	int addrlen;
+	PRInt32 af;
 #ifdef XP_UNIX
 	sigset_t oldset;
 #endif
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
+#if defined(_PR_HAVE_GETIPNODEBYADDR)
 	int error_num;
 #endif
 
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
 #ifdef XP_UNIX
 	DISABLECLOCK(&oldset);
 #endif
 	LOCK_DNS();
-#if defined(_PR_INET6)
-	if (hostaddr->raw.family == AF_INET6)
+	if (hostaddr->raw.family == PR_AF_INET6)
 	{
-		addr = &hostaddr->ipv6.ip;
-		addrlen = sizeof(hostaddr->ipv6.ip);
+#if defined(_PR_INET6_PROBE)
+		if (_pr_ipv6_is_present == PR_TRUE)
+			af = AF_INET6;
+		else
+			af = AF_INET;
+#elif defined(_PR_INET6)
+		af = AF_INET6;
+#else
+		af = AF_INET;
+#endif
 	}
 	else
-#endif /* defined(_PR_INET6) */
 	{
 		PR_ASSERT(hostaddr->raw.family == AF_INET);
+		af = AF_INET;
+	}
+	if (hostaddr->raw.family == PR_AF_INET6) {
+#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+		if (af == AF_INET6) {
+			addr = &hostaddr->ipv6.ip;
+			addrlen = sizeof(hostaddr->ipv6.ip);
+		}
+		else
+#endif
+		{
+			PR_ASSERT(af == AF_INET);
+			if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) {
+				PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+				return rv;
+			}
+			tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)
+												&hostaddr->ipv6.ip);
+			addr = &tmp_ip;
+			addrlen = sizeof(tmp_ip);
+		}
+	} else {
+		PR_ASSERT(hostaddr->raw.family == AF_INET);
+		PR_ASSERT(af == AF_INET);
 		addr = &hostaddr->inet.ip;
 		addrlen = sizeof(hostaddr->inet.ip);
 	}
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
-	h = getipnodebyaddr(addr, addrlen, hostaddr->raw.family, &error_num);
-#else
+
+#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6)
+	h = getipnodebyaddr(addr, addrlen, af, &error_num);
+#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE)
+    if (_pr_ipv6_is_present == PR_TRUE)
+    	h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen,
+				af, &error_num);
+	else
+		h = gethostbyaddr(addr, addrlen, af);
+#else	/* _PR_HAVE_GETIPNODEBYADDR */
 #ifdef XP_OS2_VACPP
-	h = gethostbyaddr((char *)addr, addrlen, hostaddr->raw.family);
+	h = gethostbyaddr((char *)addr, addrlen, af);
 #else
-	h = gethostbyaddr(addr, addrlen, hostaddr->raw.family);
+	h = gethostbyaddr(addr, addrlen, af);
 #endif
-#endif /* _PR_INET6 && _PR_HAVE_GETIPNODEBYADDR */
+#endif /* _PR_HAVE_GETIPNODEBYADDR */
 	if (NULL == h)
 	{
 #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
 		PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+		else
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 #else
 		PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 #endif
 	}
 	else
 	{
-#if defined(_PR_INET6)
 		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
-		if (hostaddr->raw.family == AF_INET6) {
-			if (IN6_IS_ADDR_V4MAPPED((struct in6_addr*)addr)) {
-				conversion = _PRIPAddrIPv4Mapped;
-			} else if (IN6_IS_ADDR_V4COMPAT((struct in6_addr*)addr)) {
-				conversion = _PRIPAddrIPv4Compat;
+		if (hostaddr->raw.family == PR_AF_INET6) {
+			if (af == AF_INET) {
+				if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*)
+												&hostaddr->ipv6.ip)) {
+					conversion = _PRIPAddrIPv4Mapped;
+				} else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *)
+													&hostaddr->ipv6.ip)) {
+					conversion = _PRIPAddrIPv4Compat;
+				}
 			}
 		}
-		rv = CopyHostent(h, buf, bufsize, conversion, hostentry);
-#else
-		rv = CopyHostent(h, buf, bufsize, hostentry);
-#endif
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry);
 		if (PR_SUCCESS != rv) {
 		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
 		}
 #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
 		freehostent(h);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+			(*((_pr_freehostent_t)_pr_freehostent_fp))(h);
 #endif
 	}
 	UNLOCK_DNS();
 #ifdef XP_UNIX
 	ENABLECLOCK(&oldset);
 #endif
 	return rv;
 }
@@ -802,19 +872,21 @@ PR_IMPLEMENT(PRUintn) PR_NetAddrSize(con
      * struct sockaddr_in6.  PRNetAddr's ipv6 member has a
      * scope_id field to match the new field.  In order to
      * work with older implementations supporting RFC 2133,
      * we take the size of struct sockaddr_in6 instead of
      * addr->ipv6.
      */
     if (AF_INET == addr->raw.family)
         addrsize = sizeof(addr->inet);
+    else if (PR_AF_INET6 == addr->raw.family)
 #if defined(_PR_INET6)
-    else if (AF_INET6 == addr->raw.family)
         addrsize = sizeof(struct sockaddr_in6);
+#else
+        addrsize = sizeof(addr->ipv6);
 #endif
 #if defined(XP_UNIX)
     else if (AF_UNIX == addr->raw.family)
         addrsize = sizeof(addr->local);
 #endif
     else addrsize = 0;
 
     return addrsize;
@@ -824,110 +896,86 @@ PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt
     PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address)
 {
     void *addr = hostEnt->h_addr_list[enumIndex++];
     memset(address, 0, sizeof(PRNetAddr));
     if (NULL == addr) enumIndex = 0;
     else
     {
         address->raw.family = hostEnt->h_addrtype;
-#if defined(_PR_INET6)
-        if (AF_INET6 == hostEnt->h_addrtype)
+        if (PR_AF_INET6 == hostEnt->h_addrtype)
         {
             address->ipv6.port = htons(port);
+        	address->ipv6.flowinfo = 0;
+        	address->ipv6.scope_id = 0;
             memcpy(&address->ipv6.ip, addr, hostEnt->h_length);
         }
         else
-#endif /* defined(_PR_INET6) */
         {
             PR_ASSERT(AF_INET == hostEnt->h_addrtype);
             address->inet.port = htons(port);
             memcpy(&address->inet.ip, addr, hostEnt->h_length);
         }
     }
     return enumIndex;
 }  /* PR_EnumerateHostEnt */
 
 PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr(
     PRNetAddrValue val, PRUint16 port, PRNetAddr *addr)
 {
     PRStatus rv = PR_SUCCESS;
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
-#if defined(_PR_INET6)
-    if (_pr_ipv6_enabled)
-    {
-        addr->ipv6.family = AF_INET6;
-        addr->ipv6.port = htons(port);
-        switch (val)
-        {
-        case PR_IpAddrNull:
-            break;  /* don't overwrite the address */
-        case PR_IpAddrAny:
-            addr->ipv6.ip = in6addr_any;
-            break;
-        case PR_IpAddrLoopback:
-            addr->ipv6.ip = in6addr_loopback;
-            break;
-        default:
-            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-            rv = PR_FAILURE;
-        }
-    }
-    else
-#endif  /* defined(_PR_INET6) */
-    {
-        addr->inet.family = AF_INET;
-        addr->inet.port = htons(port);
-        switch (val)
-        {
-        case PR_IpAddrNull:
-            break;  /* don't overwrite the address */
-        case PR_IpAddrAny:
-            addr->inet.ip = htonl(INADDR_ANY);
-            break;
-        case PR_IpAddrLoopback:
-            addr->inet.ip = htonl(INADDR_LOOPBACK);
-            break;
-        default:
-            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-            rv = PR_FAILURE;
-        }
-    }
+	addr->inet.family = AF_INET;
+	addr->inet.port = htons(port);
+	switch (val)
+	{
+	case PR_IpAddrNull:
+		break;  /* don't overwrite the address */
+	case PR_IpAddrAny:
+		addr->inet.ip = htonl(INADDR_ANY);
+		break;
+	case PR_IpAddrLoopback:
+		addr->inet.ip = htonl(INADDR_LOOPBACK);
+		break;
+	default:
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		rv = PR_FAILURE;
+	}
     return rv;
 }  /* PR_InitializeNetAddr */
 
 PR_IMPLEMENT(PRStatus) PR_SetNetAddr(
     PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr)
 {
     PRStatus rv = PR_SUCCESS;
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
     addr->raw.family = af;
-#if defined(_PR_INET6)
-    if (af == AF_INET6)
+    if (af == PR_AF_INET6)
     {
         addr->ipv6.port = htons(port);
+        addr->ipv6.flowinfo = 0;
+        addr->ipv6.scope_id = 0;
         switch (val)
         {
         case PR_IpAddrNull:
             break;  /* don't overwrite the address */
         case PR_IpAddrAny:
-            addr->ipv6.ip = in6addr_any;
+            addr->ipv6.ip = _pr_in6addr_any;
             break;
         case PR_IpAddrLoopback:
-            addr->ipv6.ip = in6addr_loopback;
+            addr->ipv6.ip = _pr_in6addr_loopback;
             break;
         default:
             PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
             rv = PR_FAILURE;
         }
     }
     else
-#endif  /* defined(_PR_INET6) */
     {
         addr->inet.port = htons(port);
         switch (val)
         {
         case PR_IpAddrNull:
             break;  /* don't overwrite the address */
         case PR_IpAddrAny:
             addr->inet.ip = htonl(INADDR_ANY);
@@ -941,75 +989,302 @@ PR_IMPLEMENT(PRStatus) PR_SetNetAddr(
         }
     }
     return rv;
 }  /* PR_SetNetAddr */
 
 PR_IMPLEMENT(PRBool)
 PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
 {
-#if defined(_PR_INET6)
-    if (addr->raw.family == AF_INET6) {
-        if (val == PR_IpAddrAny
-                && IN6_IS_ADDR_UNSPECIFIED((struct in6_addr*)&addr->ipv6.ip)) {
-            return PR_TRUE;
-        } else if (val == PR_IpAddrLoopback
-                && IN6_IS_ADDR_LOOPBACK((struct in6_addr*)&addr->ipv6.ip)) {
+    if (addr->raw.family == PR_AF_INET6) {
+        if (val == PR_IpAddrAny) {
+			if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) {
+            	return PR_TRUE;
+			} else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+					&& _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+							== htonl(INADDR_ANY)) {
+            	return PR_TRUE;
+			}
+        } else if (val == PR_IpAddrLoopback) {
+            if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) {
+            	return PR_TRUE;
+			} else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+					&& _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+							== htonl(INADDR_LOOPBACK)) {
+            	return PR_TRUE;
+			}
+        } else if (val == PR_IpAddrV4Mapped
+                && _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) {
             return PR_TRUE;
         }
-    }
-    else
-#endif
-    {
+    } else {
         if (addr->raw.family == AF_INET) {
             if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) {
                 return PR_TRUE;
             } else if (val == PR_IpAddrLoopback
                     && addr->inet.ip == htonl(INADDR_LOOPBACK)) {
                 return PR_TRUE;
             }
         }
     }
     return PR_FALSE;
 }
 
-PR_IMPLEMENT(PRNetAddr*) PR_CreateNetAddr(PRNetAddrValue val, PRUint16 port)
+#ifndef _PR_INET6
+#define XX 127
+static const unsigned char index_hex[256] = {
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+     0, 1, 2, 3,  4, 5, 6, 7,  8, 9,XX,XX, XX,XX,XX,XX,
+    XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+};
+
+/*
+ * StringToV6Addr() returns 1 if the conversion succeeds,
+ * or 0 if the input is not a valid IPv6 address string.
+ * (Same as inet_pton(AF_INET6, string, addr).)
+ */
+static int StringToV6Addr(const char *string, PRIPv6Addr *addr)
 {
-    PRNetAddr *addr = NULL;
-    if ((PR_IpAddrAny == val) || (PR_IpAddrLoopback == val))
-    {
-        addr = PR_NEWZAP(PRNetAddr);
-        if (NULL == addr)
-            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-        else
-            if (PR_FAILURE == PR_InitializeNetAddr(val, port, addr))
-                PR_DELETE(addr);  /* and that will make 'addr' == NULL */
+    const unsigned char *s = (const unsigned char *)string;
+    int section = 0;        /* index of the current section (a 16-bit
+                             * piece of the address */
+    int double_colon = -1;  /* index of the section after the first
+                             * 16-bit group of zeros represented by
+                             * the double colon */
+    unsigned int val;
+    int len;
+
+    /* Handle initial (double) colon */
+    if (*s == ':') {
+        if (s[1] != ':') return 0;
+        s += 2;
+        addr->pr_s6_addr16[0] = 0;
+        section = double_colon = 1;
+    }
+
+    while (*s) {
+        if (section == 8) return 0; /* too long */
+        if (*s == ':') {
+            if (double_colon != -1) return 0; /* two double colons */
+            addr->pr_s6_addr16[section++] = 0;
+            double_colon = section;
+            s++;
+            continue;
+        }
+        for (len = val = 0; len < 4 && index_hex[*s] != XX; len++) {
+            val = (val << 4) + index_hex[*s++];
+        }
+        if (*s == '.') {
+            if (len == 0) return 0; /* nothing between : and . */
+            break;
+        }
+        if (*s == ':') {
+            s++;
+            if (!*s) return 0; /* cannot end with single colon */
+        } else if (*s) {
+            return 0; /* bad character */
+        }
+        addr->pr_s6_addr16[section++] = htons((unsigned short)val);
+    }
+    
+    if (*s == '.') {
+        /* Have a trailing v4 format address */
+        if (section > 6) return 0; /* not enough room */
+
+        /*
+         * The number before the '.' is decimal, but we parsed it
+         * as hex.  That means it is in BCD.  Check it for validity
+         * and convert it to binary.
+         */
+        if (val > 0x0255 || (val & 0xf0) > 0x90 || (val & 0xf) > 9) return 0;
+        val = (val >> 8) * 100 + ((val >> 4) & 0xf) * 10 + (val & 0xf);
+        addr->pr_s6_addr[2 * section] = val;
+
+        s++;
+        val = index_hex[*s++];
+        if (val > 9) return 0;
+        while (*s >= '0' && *s <= '9') {
+            val = val * 10 + *s++ - '0';
+            if (val > 255) return 0;
+        }
+        if (*s != '.') return 0; /* must have exactly 4 decimal numbers */
+        addr->pr_s6_addr[2 * section + 1] = val;
+        section++;
+
+        s++;
+        val = index_hex[*s++];
+        if (val > 9) return 0;
+        while (*s >= '0' && *s <= '9') {
+            val = val * 10 + *s++ - '0';
+            if (val > 255) return 0;
+        }
+        if (*s != '.') return 0; /* must have exactly 4 decimal numbers */
+        addr->pr_s6_addr[2 * section] = val;
+
+        s++;
+        val = index_hex[*s++];
+        if (val > 9) return 0;
+        while (*s >= '0' && *s <= '9') {
+            val = val * 10 + *s++ - '0';
+            if (val > 255) return 0;
+        }
+        if (*s) return 0; /* must have exactly 4 decimal numbers */
+        addr->pr_s6_addr[2 * section + 1] = val;
+        section++;
+    }
+    
+    if (double_colon != -1) {
+        /* Stretch the double colon */
+        int tosection;
+        int ncopy = section - double_colon;
+        for (tosection = 7; ncopy--; tosection--) {
+            addr->pr_s6_addr16[tosection] = 
+                addr->pr_s6_addr16[double_colon + ncopy];
+        }
+        while (tosection >= double_colon) {
+            addr->pr_s6_addr16[tosection--] = 0;
+        }
+    } else if (section != 8) {
+        return 0; /* too short */
     }
-    else
-        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-    return addr;
-}  /* PR_CreateNetAddr */
+    return 1;
+}
+#undef XX
+            
+static const char *basis_hex = "0123456789abcdef";
+
+/*
+ * V6AddrToString() returns a pointer to the buffer containing
+ * the text string if the conversion succeeds, and NULL otherwise.
+ * (Same as inet_ntop(AF_INET6, addr, buf, size), except that errno
+ * is not set on failure.)
+ */
+static const char *V6AddrToString(
+    const PRIPv6Addr *addr, char *buf, PRUint32 size)
+{
+#define STUFF(c) do { \
+    if (!size--) return NULL; \
+    *buf++ = (c); \
+} while (0)
+
+    int double_colon = -1;          /* index of the first 16-bit
+                                     * group of zeros represented
+                                     * by the double colon */
+    int double_colon_length = 1;    /* use double colon only if
+                                     * there are two or more 16-bit
+                                     * groups of zeros */
+    int zero_length;
+    int section;
+    unsigned int val;
+    const char *bufcopy = buf;
+
+    /* Scan to find the placement of the double colon */
+    for (section = 0; section < 8; section++) {
+        if (addr->pr_s6_addr16[section] == 0) {
+            zero_length = 1;
+            section++;
+            while (section < 8 && addr->pr_s6_addr16[section] == 0) {
+                zero_length++;
+                section++;
+            }
+            /* Select the longest sequence of zeros */
+            if (zero_length > double_colon_length) {
+                double_colon = section - zero_length;
+                double_colon_length = zero_length;
+            }
+        }
+    }
+
+    /* Now start converting to a string */
+    section = 0;
 
-PR_IMPLEMENT(PRStatus) PR_DestroyNetAddr(PRNetAddr *addr)
-{
-    PR_Free(addr);
-    return PR_SUCCESS;
-}  /* PR_DestroyNetAddr */
+    if (double_colon == 0) {
+        if (double_colon_length == 6 ||
+            (double_colon_length == 5 && addr->pr_s6_addr16[5] == 0xffff)) {
+            /* ipv4 format address */
+            STUFF(':');
+            STUFF(':');
+            if (double_colon_length == 5) {
+                STUFF('f');
+                STUFF('f');
+                STUFF('f');
+                STUFF('f');
+                STUFF(':');
+            }
+            if (addr->pr_s6_addr[12] > 99) STUFF(addr->pr_s6_addr[12]/100 + '0');
+            if (addr->pr_s6_addr[12] > 9) STUFF((addr->pr_s6_addr[12]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[12]%10 + '0');
+            STUFF('.');
+            if (addr->pr_s6_addr[13] > 99) STUFF(addr->pr_s6_addr[13]/100 + '0');
+            if (addr->pr_s6_addr[13] > 9) STUFF((addr->pr_s6_addr[13]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[13]%10 + '0');
+            STUFF('.');
+            if (addr->pr_s6_addr[14] > 99) STUFF(addr->pr_s6_addr[14]/100 + '0');
+            if (addr->pr_s6_addr[14] > 9) STUFF((addr->pr_s6_addr[14]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[14]%10 + '0');
+            STUFF('.');
+            if (addr->pr_s6_addr[15] > 99) STUFF(addr->pr_s6_addr[15]/100 + '0');
+            if (addr->pr_s6_addr[15] > 9) STUFF((addr->pr_s6_addr[15]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[15]%10 + '0');
+            STUFF('\0');
+            return bufcopy;
+        }
+    }
+
+    while (section < 8) {
+        if (section == double_colon) {
+            STUFF(':');
+            STUFF(':');
+            section += double_colon_length;
+            continue;
+        }
+        val = ntohs(addr->pr_s6_addr16[section]);
+        if (val > 0xfff) {
+            STUFF(basis_hex[val >> 12]);
+        }
+        if (val > 0xff) {
+            STUFF(basis_hex[(val >> 8) & 0xf]);
+        }
+        if (val > 0xf) {
+            STUFF(basis_hex[(val >> 4) & 0xf]);
+        }
+        STUFF(basis_hex[val & 0xf]);
+        section++;
+        if (section < 8 && section != double_colon) STUFF(':');
+    }
+    STUFF('\0');
+    return bufcopy;
+#undef STUFF    
+}
+
+#endif /* !_PR_INET6 */
 
 PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
 {
     PRStatus status = PR_SUCCESS;
+    PRIntn rv;
 
 #if defined(_PR_INET6)
-    PRIntn rv;
-
     rv = inet_pton(AF_INET6, string, &addr->ipv6.ip);
     if (1 == rv)
     {
-        addr->raw.family = AF_INET6;
+        addr->raw.family = PR_AF_INET6;
     }
     else
     {
         PR_ASSERT(0 == rv);
         rv = inet_pton(AF_INET, string, &addr->inet.ip);
         if (1 == rv)
         {
             addr->raw.family = AF_INET;
@@ -1017,16 +1292,23 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAdd
         else
         {
             PR_ASSERT(0 == rv);
             PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
             status = PR_FAILURE;
         }
     }
 #else /* _PR_INET6 */
+    rv = StringToV6Addr(string, &addr->ipv6.ip);
+    if (1 == rv) {
+        addr->raw.family = PR_AF_INET6;
+        return PR_SUCCESS;
+    }
+    PR_ASSERT(0 == rv);
+
     addr->inet.family = AF_INET;
 #ifdef XP_OS2_VACPP
     addr->inet.ip = inet_addr((char *)string);
 #else
     addr->inet.ip = inet_addr(string);
 #endif
     if ((PRUint32) -1 == addr->inet.ip)
     {
@@ -1039,27 +1321,30 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAdd
 #endif /* _PR_INET6 */
 
     return status;
 }
 
 PR_IMPLEMENT(PRStatus) PR_NetAddrToString(
     const PRNetAddr *addr, char *string, PRUint32 size)
 {
-#if defined(_PR_INET6)
-    if (AF_INET6 == addr->raw.family)
+    if (PR_AF_INET6 == addr->raw.family)
     {
+#if defined(_PR_INET6)
         if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size))
+#else
+        if (NULL == V6AddrToString(&addr->ipv6.ip, string, size))
+#endif
         {
-            PR_SetError(PR_INVALID_ARGUMENT_ERROR, errno);
+            /* the size of the result buffer is inadequate */
+            PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
             return PR_FAILURE;
         }
     }
     else
-#endif  /* defined(_PR_INET6) */
     {
         PR_ASSERT(AF_INET == addr->raw.family);
         PR_ASSERT(size >= 16);
         if (size < 16) goto failed;
         if (AF_INET != addr->raw.family) goto failed;
         else
         {
             unsigned char *byte = (unsigned char*)&addr->inet.ip;
@@ -1071,62 +1356,63 @@ PR_IMPLEMENT(PRStatus) PR_NetAddrToStrin
     return PR_SUCCESS;
 
 failed:
     PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
     return PR_FAILURE;
 
 }  /* PR_NetAddrToString */
 
+/*
+ * Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr
+ */
+PR_IMPLEMENT(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr)
+{
+    PRUint8 *dstp;
+    dstp = v6addr->pr_s6_addr;
+    memset(dstp, 0, 10);
+    memset(dstp + 10, 0xff, 2);
+    memcpy(dstp + 12,(char *) &v4addr, 4);
+}
+
 PR_IMPLEMENT(PRUint16) PR_ntohs(PRUint16 n) { return ntohs(n); }
 PR_IMPLEMENT(PRUint32) PR_ntohl(PRUint32 n) { return ntohl(n); }
 PR_IMPLEMENT(PRUint16) PR_htons(PRUint16 n) { return htons(n); }
 PR_IMPLEMENT(PRUint32) PR_htonl(PRUint32 n) { return htonl(n); }
 PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n)
 {
-    /*
-    ** There is currently no attempt to optomize out depending
-    ** on the host' byte order. That would be easy enough to
-    ** do.
-    */
+#ifdef IS_BIG_ENDIAN
+    return n;
+#else
     PRUint64 tmp;
     PRUint32 hi, lo;
     LL_L2UI(lo, n);
     LL_SHR(tmp, n, 32);
     LL_L2UI(hi, tmp);
     hi = PR_ntohl(hi);
     lo = PR_ntohl(lo);
-    LL_UI2L(n, hi);
+    LL_UI2L(n, lo);
     LL_SHL(n, n, 32);
-    LL_UI2L(tmp, lo);
+    LL_UI2L(tmp, hi);
     LL_ADD(n, n, tmp);
     return n;
+#endif
 }  /* ntohll */
 
 PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n)
 {
-    /*
-    ** There is currently no attempt to optomize out depending
-    ** on the host' byte order. That would be easy enough to
-    ** do.
-    */
+#ifdef IS_BIG_ENDIAN
+    return n;
+#else
     PRUint64 tmp;
     PRUint32 hi, lo;
     LL_L2UI(lo, n);
     LL_SHR(tmp, n, 32);
     LL_L2UI(hi, tmp);
     hi = htonl(hi);
     lo = htonl(lo);
-    LL_UI2L(n, hi);
+    LL_UI2L(n, lo);
     LL_SHL(n, n, 32);
-    LL_UI2L(tmp, lo);
+    LL_UI2L(tmp, hi);
     LL_ADD(n, n, tmp);
     return n;
+#endif
 }  /* htonll */
-
-PR_IMPLEMENT(PRUint16) PR_FamilyInet(void)
-{
-#ifdef _PR_INET6
-    return (_pr_ipv6_enabled ? AF_INET6 : AF_INET);
-#else
-    return AF_INET;
-#endif
-}
--- a/pr/src/misc/prtpool.c
+++ b/pr/src/misc/prtpool.c
@@ -11,17 +11,16 @@
  * NPL.
  * 
  * The Initial Developer of this code under the NPL is Netscape
  * Communications Corporation.  Portions created by Netscape are
  * Copyright (C) 1999 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
-#include "prtpool.h"
 #include "nspr.h"
 
 /*
  * Thread pools
  *	Thread pools create and manage threads to provide support for
  *	scheduling jobs onto one or more threads.
  *
  */
@@ -79,48 +78,45 @@ typedef struct io_jobq {
 /*
  * Threadpool
  */
 struct PRThreadPool {
 	PRInt32		init_threads;
 	PRInt32		max_threads;
 	PRInt32		current_threads;
 	PRInt32		idle_threads;
-	PRInt32		stacksize;
+	PRUint32	stacksize;
 	tp_jobq		jobq;
 	io_jobq		ioq;
 	timer_jobq	timerq;
+	PRLock		*join_lock;		/* used with jobp->join_cv */
 	PRCondVar	*shutdown_cv;
 	PRBool		shutdown;
 };
 
 typedef enum io_op_type
 	{ JOB_IO_READ, JOB_IO_WRITE, JOB_IO_CONNECT, JOB_IO_ACCEPT } io_op_type;
 
-typedef enum _PRJobStatus
-	{ JOB_ON_TIMERQ, JOB_ON_IOQ, JOB_QUEUED, JOB_RUNNING, JOB_COMPLETED,
-					JOB_CANCELED, JOB_FREED } _PRJobStatus;
-
-typedef void (* Jobfn)(void *arg);
-
 #ifdef OPT_WINNT
 typedef struct NT_notifier {
 	OVERLAPPED overlapped;		/* must be first */
 	PRJob	*jobp;
 } NT_notifier;
 #endif
 
 struct PRJob {
 	PRCList			links;		/* 	for linking jobs */
-	_PRJobStatus 	status;
-	PRBool			joinable;
-	Jobfn			job_func;
+	PRBool			on_ioq;		/* job on ioq */
+	PRBool			on_timerq;	/* job on timerq */
+	PRJobFn			job_func;
 	void 			*job_arg;
-	PRLock			*jlock;
 	PRCondVar		*join_cv;
+	PRBool			join_wait;	/* == PR_TRUE, when waiting to join */
+	PRCondVar		*cancel_cv;	/* for cancelling IO jobs */
+	PRBool			cancel_io;	/* for cancelling IO jobs */
 	PRThreadPool	*tpool;		/* back pointer to thread pool */
 	PRJobIoDesc		*iod;
 	io_op_type		io_op;
 	PRInt16			io_poll_flags;
 	PRNetAddr		*netaddr;
 	PRIntervalTime	timeout;	/* relative value */
 	PRIntervalTime	absolute;
 #ifdef OPT_WINNT
@@ -129,23 +125,51 @@ struct PRJob {
 };
 
 #define JOB_LINKS_PTR(_qp) \
     ((PRJob *) ((char *) (_qp) - offsetof(PRJob, links)))
 
 #define WTHREAD_LINKS_PTR(_qp) \
     ((wthread *) ((char *) (_qp) - offsetof(wthread, links)))
 
+#define JOINABLE_JOB(_jobp) (NULL != (_jobp)->join_cv)
+
+#define JOIN_NOTIFY(_jobp)								\
+				PR_BEGIN_MACRO							\
+				PR_Lock(_jobp->tpool->join_lock);		\
+				_jobp->join_wait = PR_FALSE;			\
+				PR_NotifyCondVar(_jobp->join_cv);		\
+				PR_Unlock(_jobp->tpool->join_lock);		\
+				PR_END_MACRO
+
+#define CANCEL_IO_JOB(jobp)								\
+				PR_BEGIN_MACRO							\
+				jobp->cancel_io = PR_FALSE;				\
+				jobp->on_ioq = PR_FALSE;				\
+				PR_REMOVE_AND_INIT_LINK(&jobp->links);	\
+				tp->ioq.cnt--;							\
+				PR_NotifyCondVar(jobp->cancel_cv);		\
+				PR_END_MACRO
+
 static void delete_job(PRJob *jobp);
 static PRThreadPool * alloc_threadpool();
-static PRJob * alloc_job(PRBool joinable);
+static PRJob * alloc_job(PRBool joinable, PRThreadPool *tp);
 static void notify_ioq(PRThreadPool *tp);
 static void notify_timerq(PRThreadPool *tp);
 
 /*
+ * locks are acquired in the following order
+ *
+ *	tp->ioq.lock,tp->timerq.lock
+ *			|
+ *			V
+ *		tp->jobq->lock		
+ */
+
+/*
  * worker thread function
  */
 static void wstart(void *arg)
 {
 PRThreadPool *tp = (PRThreadPool *) arg;
 PRCList *head;
 
 	/*
@@ -167,52 +191,43 @@ PRCList *head;
 		PR_ASSERT(rv);
 		if (shutdown)
 			break;
 		jobp = ((NT_notifier *) olp)->jobp;
 		PR_Lock(tp->jobq.lock);
 		tp->idle_threads--;
 		tp->jobq.cnt--;
 		PR_Unlock(tp->jobq.lock);
-		PR_Lock(jobp->jlock);
-		jobp->status = JOB_RUNNING;
-		PR_Unlock(jobp->jlock);
 #else
 
 		PR_Lock(tp->jobq.lock);
 		while (PR_CLIST_IS_EMPTY(&tp->jobq.list) && (!tp->shutdown)) {
 			tp->idle_threads++;
 			PR_WaitCondVar(tp->jobq.cv, PR_INTERVAL_NO_TIMEOUT);
+			tp->idle_threads--;
 		}	
-		tp->idle_threads--;
 		if (tp->shutdown) {
 			PR_Unlock(tp->jobq.lock);
 			break;
 		}
 		head = PR_LIST_HEAD(&tp->jobq.list);
 		/*
 		 * remove job from queue
 		 */
 		PR_REMOVE_AND_INIT_LINK(head);
 		tp->jobq.cnt--;
 		jobp = JOB_LINKS_PTR(head);
-		PR_Lock(jobp->jlock);
-		jobp->status = JOB_RUNNING;
-		PR_Unlock(jobp->jlock);
 		PR_Unlock(tp->jobq.lock);
 #endif
 
 		jobp->job_func(jobp->job_arg);
-		if (!jobp->joinable) {
+		if (!JOINABLE_JOB(jobp)) {
 			delete_job(jobp);
 		} else {
-			PR_Lock(jobp->jlock);
-			jobp->status = JOB_COMPLETED;
-			PR_NotifyCondVar(jobp->join_cv);
-			PR_Unlock(jobp->jlock);
+			JOIN_NOTIFY(jobp);
 		}
 	}
 	PR_Lock(tp->jobq.lock);
 	tp->current_threads--;
 	PR_Unlock(tp->jobq.lock);
 }
 
 /*
@@ -231,37 +246,39 @@ add_to_jobq(PRThreadPool *tp, PRJob *job
 	/*
 	 * notify worker thread(s)
 	 */
 	PostQueuedCompletionStatus(tp->jobq.nt_completion_port, 0,
             FALSE, &jobp->nt_notifier.overlapped);
 #else
 	PR_Lock(tp->jobq.lock);
 	PR_APPEND_LINK(&jobp->links,&tp->jobq.list);
-	jobp->status = JOB_QUEUED;
 	tp->jobq.cnt++;
 	if ((tp->idle_threads < tp->jobq.cnt) &&
 					(tp->current_threads < tp->max_threads)) {
-		PRThread *thr;
 		wthread *wthrp;
 		/*
 		 * increment thread count and unlock the jobq lock
 		 */
 		tp->current_threads++;
 		PR_Unlock(tp->jobq.lock);
 		/* create new worker thread */
-		thr = PR_CreateThread(PR_USER_THREAD, wstart,
+		wthrp = PR_NEWZAP(wthread);
+		if (wthrp) {
+			wthrp->thread = PR_CreateThread(PR_USER_THREAD, wstart,
 						tp, PR_PRIORITY_NORMAL,
 						PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,tp->stacksize);
+			if (NULL == wthrp->thread) {
+				PR_DELETE(wthrp);  /* this sets wthrp to NULL */
+			}
+		}
 		PR_Lock(tp->jobq.lock);
-		if (NULL == thr) {
+		if (NULL == wthrp) {
 			tp->current_threads--;
 		} else {
-			wthrp = PR_NEWZAP(wthread);
-			wthrp->thread = thr;
 			PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads);
 		}
 	}
 	/*
 	 * wakeup a worker thread
 	 */
 	PR_NotifyCondVar(tp->jobq.cv);
 	PR_Unlock(tp->jobq.lock);
@@ -326,16 +343,20 @@ PRIntervalTime now;
 		polljobs[pollfds_used] = NULL;
 		pollfds_used++;
 		/*
 		 * fill in the pollfd array
 		 */
 		PR_Lock(tp->ioq.lock);
 		for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = qp->next) {
 			jobp = JOB_LINKS_PTR(qp);
+			if (jobp->cancel_io) {
+				CANCEL_IO_JOB(jobp);
+				continue;
+			}
 			if (pollfds_used == (pollfd_cnt))
 				break;
 			pollfds[pollfds_used].fd = jobp->iod->socket;
 			pollfds[pollfds_used].in_flags = jobp->io_poll_flags;
 			pollfds[pollfds_used].out_flags = 0;
 			polljobs[pollfds_used] = jobp;
 
 			pollfds_used++;
@@ -386,61 +407,88 @@ PRIntervalTime now;
 			}
 
 			for(index = 1; index < (pollfds_used); index++) {
                 PRInt16 events = pollfds[index].in_flags;
                 PRInt16 revents = pollfds[index].out_flags;	
 				jobp = polljobs[index];	
 
                 if ((revents & PR_POLL_NVAL) ||  /* busted in all cases */
+                	(revents & PR_POLL_ERR) ||
                 			((events & PR_POLL_WRITE) &&
 							(revents & PR_POLL_HUP))) { /* write op & hup */
 					PR_Lock(tp->ioq.lock);
+					if (jobp->cancel_io) {
+						CANCEL_IO_JOB(jobp);
+						PR_Unlock(tp->ioq.lock);
+						continue;
+					}
 					PR_REMOVE_AND_INIT_LINK(&jobp->links);
 					tp->ioq.cnt--;
+					jobp->on_ioq = PR_FALSE;
 					PR_Unlock(tp->ioq.lock);
 
 					/* set error */
                     if (PR_POLL_NVAL & revents)
 						jobp->iod->error = PR_BAD_DESCRIPTOR_ERROR;
                     else if (PR_POLL_HUP & revents)
 						jobp->iod->error = PR_CONNECT_RESET_ERROR;
+                    else 
+						jobp->iod->error = PR_IO_ERROR;
 
 					/*
 					 * add to jobq
 					 */
 					add_to_jobq(tp, jobp);
-				} else if (revents & events) {
+				} else if (revents) {
 					/*
 					 * add to jobq
 					 */
 					PR_Lock(tp->ioq.lock);
+					if (jobp->cancel_io) {
+						CANCEL_IO_JOB(jobp);
+						PR_Unlock(tp->ioq.lock);
+						continue;
+					}
 					PR_REMOVE_AND_INIT_LINK(&jobp->links);
 					tp->ioq.cnt--;
+					jobp->on_ioq = PR_FALSE;
 					PR_Unlock(tp->ioq.lock);
 
-					jobp->iod->error = 0;
+					if (jobp->io_op == JOB_IO_CONNECT) {
+						if (PR_GetConnectStatus(&pollfds[index]) == PR_SUCCESS)
+							jobp->iod->error = 0;
+						else
+							jobp->iod->error = PR_GetError();
+					} else
+						jobp->iod->error = 0;
+
 					add_to_jobq(tp, jobp);
 				}
 			}
 		}
 		/*
 		 * timeout processing
 		 */
 		now = PR_IntervalNow();
 		PR_Lock(tp->ioq.lock);
 		for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = qp->next) {
 			jobp = JOB_LINKS_PTR(qp);
+			if (jobp->cancel_io) {
+				CANCEL_IO_JOB(jobp);
+				continue;
+			}
 			if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout)
 				break;
 			if ((PR_INTERVAL_NO_WAIT != jobp->timeout) &&
 								((PRInt32)(jobp->absolute - now) > 0))
 				break;
 			PR_REMOVE_AND_INIT_LINK(&jobp->links);
 			tp->ioq.cnt--;
+			jobp->on_ioq = PR_FALSE;
 			jobp->iod->error = PR_IO_TIMEOUT_ERROR;
 			add_to_jobq(tp, jobp);
 		}
 		PR_Unlock(tp->ioq.lock);
 	}
 }
 
 /*
@@ -489,32 +537,35 @@ PRIntervalTime now;
 			if ((PRInt32)(jobp->absolute - now) > 0) {
 				break;
 			}
 			/*
 			 * job timed out
 			 */
 			PR_REMOVE_AND_INIT_LINK(&jobp->links);
 			tp->timerq.cnt--;
+			jobp->on_timerq = PR_FALSE;
 			add_to_jobq(tp, jobp);
 		}
 		PR_Unlock(tp->timerq.lock);
 	}
 }
 
 static void
 delete_threadpool(PRThreadPool *tp)
 {
 	if (NULL != tp) {
 		if (NULL != tp->shutdown_cv)
 			PR_DestroyCondVar(tp->shutdown_cv);
 		if (NULL != tp->jobq.cv)
 			PR_DestroyCondVar(tp->jobq.cv);
 		if (NULL != tp->jobq.lock)
 			PR_DestroyLock(tp->jobq.lock);
+		if (NULL != tp->join_lock)
+			PR_DestroyLock(tp->join_lock);
 #ifdef OPT_WINNT
 		if (NULL != tp->jobq.nt_completion_port)
 			CloseHandle(tp->jobq.nt_completion_port);
 #endif
 		/* Timer queue */
 		if (NULL != tp->timerq.cv)
 			PR_DestroyCondVar(tp->timerq.cv);
 		if (NULL != tp->timerq.lock)
@@ -540,16 +591,19 @@ PRThreadPool *tp;
 	if (NULL == tp)
 		goto failed;
 	tp->jobq.lock = PR_NewLock();
 	if (NULL == tp->jobq.lock)
 		goto failed;
 	tp->jobq.cv = PR_NewCondVar(tp->jobq.lock);
 	if (NULL == tp->jobq.cv)
 		goto failed;
+	tp->join_lock = PR_NewLock();
+	if (NULL == tp->join_lock)
+		goto failed;
 #ifdef OPT_WINNT
 	tp->jobq.nt_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
 									NULL, 0, 0);
 	if (NULL == tp->jobq.nt_completion_port)
 		goto failed;
 #endif
 
 	tp->ioq.lock = PR_NewLock();
@@ -576,17 +630,17 @@ failed:
 	delete_threadpool(tp);
 	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
 	return NULL;
 }
 
 /* Create thread pool */
 PR_IMPLEMENT(PRThreadPool *)
 PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads,
-                                PRSize stacksize)
+                                PRUint32 stacksize)
 {
 PRThreadPool *tp;
 PRThread *thr;
 int i;
 wthread *wthrp;
 
 	tp = alloc_threadpool();
 	if (NULL == tp)
@@ -638,42 +692,39 @@ wthread *wthrp;
 	PR_Unlock(tp->jobq.lock);
 	return tp;
 }
 
 static void
 delete_job(PRJob *jobp)
 {
 	if (NULL != jobp) {
-		if (NULL != jobp->jlock) {
-			PR_DestroyLock(jobp->jlock);
-			jobp->jlock = NULL;
-		}
 		if (NULL != jobp->join_cv) {
 			PR_DestroyCondVar(jobp->join_cv);
 			jobp->join_cv = NULL;
 		}
-		jobp->status = JOB_FREED;
+		if (NULL != jobp->cancel_cv) {
+			PR_DestroyCondVar(jobp->cancel_cv);
+			jobp->cancel_cv = NULL;
+		}
 		PR_DELETE(jobp);
 	}
 }
 
 static PRJob *
-alloc_job(PRBool joinable)
+alloc_job(PRBool joinable, PRThreadPool *tp)
 {
 	PRJob *jobp;
 
 	jobp = PR_NEWZAP(PRJob);
 	if (NULL == jobp) 
 		goto failed;
-	jobp->jlock = PR_NewLock();
-	if (NULL == jobp->jlock)
-		goto failed;
 	if (joinable) {
-		jobp->join_cv = PR_NewCondVar(jobp->jlock);
+		jobp->join_cv = PR_NewCondVar(tp->join_lock);
+		jobp->join_wait = PR_TRUE;
 		if (NULL == jobp->join_cv)
 			goto failed;
 	} else {
 		jobp->join_cv = NULL;
 	}
 #ifdef OPT_WINNT
 	jobp->nt_notifier.jobp = jobp;
 #endif
@@ -681,69 +732,66 @@ alloc_job(PRBool joinable)
 failed:
 	delete_job(jobp);
 	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
 	return NULL;
 }
 
 /* queue a job */
 PR_IMPLEMENT(PRJob *)
-PR_QueueJob(PRThreadPool *tpool, JobFn fn, void *arg, PRBool joinable)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable)
 {
 	PRJob *jobp;
 
-	jobp = alloc_job(joinable);
+	jobp = alloc_job(joinable, tpool);
 	if (NULL == jobp)
 		return NULL;
 
 	jobp->job_func = fn;
 	jobp->job_arg = arg;
 	jobp->tpool = tpool;
-	jobp->joinable = joinable;
 
 	add_to_jobq(tpool, jobp);
 	return jobp;
 }
 
-/* queue a job, when a socket is readable */
+/* queue a job, when a socket is readable or writeable */
 static PRJob *
-queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
+queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg,
 				PRBool joinable, io_op_type op)
 {
 	PRJob *jobp;
 	PRIntervalTime now;
 
-	jobp = alloc_job(joinable);
+	jobp = alloc_job(joinable, tpool);
 	if (NULL == jobp) {
 		return NULL;
 	}
 
 	/*
 	 * Add a new job to io_jobq
 	 * wakeup io worker thread
 	 */
 
 	jobp->job_func = fn;
 	jobp->job_arg = arg;
-	jobp->status = JOB_ON_IOQ;
 	jobp->tpool = tpool;
-	jobp->joinable = joinable;
 	jobp->iod = iod;
 	if (JOB_IO_READ == op) {
 		jobp->io_op = JOB_IO_READ;
 		jobp->io_poll_flags = PR_POLL_READ;
 	} else if (JOB_IO_WRITE == op) {
 		jobp->io_op = JOB_IO_WRITE;
 		jobp->io_poll_flags = PR_POLL_WRITE;
 	} else if (JOB_IO_ACCEPT == op) {
 		jobp->io_op = JOB_IO_ACCEPT;
 		jobp->io_poll_flags = PR_POLL_READ;
 	} else if (JOB_IO_CONNECT == op) {
 		jobp->io_op = JOB_IO_CONNECT;
-		jobp->io_poll_flags = PR_POLL_WRITE;
+		jobp->io_poll_flags = PR_POLL_WRITE|PR_POLL_EXCEPT;
 	} else {
 		delete_job(jobp);
 		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
 		return NULL;
 	}
 
 	jobp->timeout = iod->timeout;
 	if ((PR_INTERVAL_NO_TIMEOUT == iod->timeout) ||
@@ -773,101 +821,114 @@ queue_io_job(PRThreadPool *tpool, PRJobI
 			tmp_jobp = JOB_LINKS_PTR(qp);
 			if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) {
 				break;
 			}
 		}
 		PR_INSERT_AFTER(&jobp->links,qp);
 	}
 
+	jobp->on_ioq = PR_TRUE;
 	tpool->ioq.cnt++;
 	/*
 	 * notify io worker thread(s)
 	 */
 	PR_Unlock(tpool->ioq.lock);
 	notify_ioq(tpool);
 	return jobp;
 }
 
 /* queue a job, when a socket is readable */
 PR_IMPLEMENT(PRJob *)
-PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
+PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg,
 											PRBool joinable)
 {
 	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_READ));
 }
 
 /* queue a job, when a socket is writeable */
 PR_IMPLEMENT(PRJob *)
-PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn,void * arg,
+PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,void * arg,
 										PRBool joinable)
 {
 	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_WRITE));
 }
 
 
 /* queue a job, when a socket has a pending connection */
 PR_IMPLEMENT(PRJob *)
-PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
-												PRBool joinable)
+PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,
+								void * arg, PRBool joinable)
 {
 	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_ACCEPT));
 }
 
 /* queue a job, when a socket can be connected */
 PR_IMPLEMENT(PRJob *)
-PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod, PRNetAddr *addr,
-				JobFn fn, void * arg, PRBool joinable)
+PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
+			const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable)
 {
-	/*
-	 * not implemented
-	 */
-	 return NULL;
+	PRStatus rv;
+	PRErrorCode err;
+
+	rv = PR_Connect(iod->socket, addr, PR_INTERVAL_NO_WAIT);
+	if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){
+		/* connection pending */
+		return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT));
+	} else {
+		/*
+		 * connection succeeded or failed; add to jobq right away
+		 */
+		if (rv == PR_FAILURE)
+			iod->error = err;
+		else
+			iod->error = 0;
+		return(PR_QueueJob(tpool, fn, arg, joinable));
+	}
 }
 
 /* queue a job, when a timer expires */
 PR_IMPLEMENT(PRJob *)
 PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
-							JobFn fn, void * arg, PRBool joinable)
+							PRJobFn fn, void * arg, PRBool joinable)
 {
 	PRIntervalTime now;
 	PRJob *jobp;
 
 	if (PR_INTERVAL_NO_TIMEOUT == timeout) {
 		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
 		return NULL;
 	}
 	if (PR_INTERVAL_NO_WAIT == timeout) {
 		/*
 		 * no waiting; add to jobq right away
 		 */
 		return(PR_QueueJob(tpool, fn, arg, joinable));
 	}
-	jobp = alloc_job(joinable);
+	jobp = alloc_job(joinable, tpool);
 	if (NULL == jobp) {
 		return NULL;
 	}
 
 	/*
 	 * Add a new job to timer_jobq
 	 * wakeup timer worker thread
 	 */
 
 	jobp->job_func = fn;
 	jobp->job_arg = arg;
-	jobp->status = JOB_ON_TIMERQ;
 	jobp->tpool = tpool;
-	jobp->joinable = joinable;
 	jobp->timeout = timeout;
 
 	now = PR_IntervalNow();
 	jobp->absolute = now + timeout;
 
 
 	PR_Lock(tpool->timerq.lock);
+	jobp->on_timerq = PR_TRUE;
 	if (PR_CLIST_IS_EMPTY(&tpool->timerq.list))
 		PR_APPEND_LINK(&jobp->links,&tpool->timerq.list);
 	else {
 		PRCList *qp;
 		PRJob *tmp_jobp;
 		/*
 		 * insert into the sorted timer jobq
 		 */
@@ -916,57 +977,89 @@ PRStatus rval_status;
  *	XXXX: is this needed? likely to be removed
  */
 PR_IMPLEMENT(PRStatus)
 PR_CancelJob(PRJob *jobp) {
 
 	PRStatus rval = PR_FAILURE;
 	PRThreadPool *tp;
 
-	if (JOB_QUEUED == jobp->status) {
+	if (jobp->on_timerq) {
 		/*
-		 * now, check again while holding thread pool lock
+		 * now, check again while holding the timerq lock
+		 */
+		tp = jobp->tpool;
+		PR_Lock(tp->timerq.lock);
+		if (jobp->on_timerq) {
+			jobp->on_timerq = PR_FALSE;
+			PR_REMOVE_AND_INIT_LINK(&jobp->links);
+			tp->timerq.cnt--;
+			PR_Unlock(tp->timerq.lock);
+			if (!JOINABLE_JOB(jobp)) {
+				delete_job(jobp);
+			} else {
+				JOIN_NOTIFY(jobp);
+			}
+			rval = PR_SUCCESS;
+		} else
+			PR_Unlock(tp->timerq.lock);
+	} else if (jobp->on_ioq) {
+		/*
+		 * now, check again while holding the ioq lock
 		 */
 		tp = jobp->tpool;
-		PR_Lock(tp->jobq.lock);
-		PR_Lock(jobp->jlock);
-		if (JOB_QUEUED == jobp->status) {
-			PR_REMOVE_AND_INIT_LINK(&jobp->links);
-			if (!jobp->joinable) {
-				PR_Unlock(jobp->jlock);
+		PR_Lock(tp->ioq.lock);
+		if (jobp->on_ioq) {
+			jobp->cancel_cv = PR_NewCondVar(tp->ioq.lock);
+			if (NULL == jobp->cancel_cv) {
+				PR_Unlock(tp->ioq.lock);
+				PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+				return PR_FAILURE;
+			}
+			/*
+			 * mark job 'cancelled' and notify io thread(s)
+			 * XXXX:
+			 *		this assumes there is only one io thread; when there
+			 * 		are multiple threads, the io thread processing this job
+			 * 		must be notified.
+			 */
+			jobp->cancel_io = PR_TRUE;
+			PR_Unlock(tp->ioq.lock);	/* release, reacquire ioq lock */
+			notify_ioq(tp);
+			PR_Lock(tp->ioq.lock);
+			while (jobp->cancel_io)
+				PR_WaitCondVar(jobp->cancel_cv, PR_INTERVAL_NO_TIMEOUT);
+			PR_Unlock(tp->ioq.lock);
+			PR_ASSERT(!jobp->on_ioq);
+			if (!JOINABLE_JOB(jobp)) {
 				delete_job(jobp);
 			} else {
-				jobp->status = JOB_CANCELED;
-				PR_NotifyCondVar(jobp->join_cv);
-				PR_Unlock(jobp->jlock);
+				JOIN_NOTIFY(jobp);
 			}
 			rval = PR_SUCCESS;
-		}
-		PR_Unlock(tp->jobq.lock);
+		} else
+			PR_Unlock(tp->ioq.lock);
 	}
+	if (PR_FAILURE == rval)
+		PR_SetError(PR_INVALID_STATE_ERROR, 0);
 	return rval;
 }
 
 /* join a job, wait until completion */
 PR_IMPLEMENT(PRStatus)
 PR_JoinJob(PRJob *jobp)
 {
-	/*
-	 * No references to the thread pool
-	 */
-	if (!jobp->joinable) {
+	if (!JOINABLE_JOB(jobp)) {
 		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
 		return PR_FAILURE;
 	}
-	PR_Lock(jobp->jlock);
-	while((JOB_COMPLETED != jobp->status) &&
-			(JOB_CANCELED != jobp->status))
+	PR_Lock(jobp->tpool->join_lock);
+	while(jobp->join_wait)
 		PR_WaitCondVar(jobp->join_cv, PR_INTERVAL_NO_TIMEOUT);
-
-	PR_Unlock(jobp->jlock);
+	PR_Unlock(jobp->tpool->join_lock);
 	delete_job(jobp);
 	return PR_SUCCESS;
 }
 
 /* shutdown threadpool */
 PR_IMPLEMENT(PRStatus)
 PR_ShutdownThreadPool(PRThreadPool *tpool)
 {
@@ -1012,19 +1105,17 @@ PRStatus rval_status;
 	}
 #else
 	PR_NotifyAllCondVar(tpool->jobq.cv);
 #endif
 
 	/*
 	 * wakeup io thread(s)
 	 */
-	PR_Lock(tpool->ioq.lock);
 	notify_ioq(tpool);
-	PR_Unlock(tpool->ioq.lock);
 
 	/*
 	 * wakeup timer thread(s)
 	 */
 	PR_Lock(tpool->timerq.lock);
 	notify_timerq(tpool);
 	PR_Unlock(tpool->timerq.lock);
 
@@ -1059,68 +1150,48 @@ PRStatus rval_status;
 		PR_REMOVE_AND_INIT_LINK(head);
 		wthrp = WTHREAD_LINKS_PTR(head);
 		rval_status = PR_JoinThread(wthrp->thread);
 		PR_ASSERT(PR_SUCCESS == rval_status);
 		PR_DELETE(wthrp);
 	}
 
 	/*
-	 * Delete unjoinable jobs; joinable jobs must be reclaimed by the user
+	 * Delete queued jobs
 	 */
 	while (!PR_CLIST_IS_EMPTY(&tpool->jobq.list)) {
 		PRJob *jobp;
 
 		head = PR_LIST_HEAD(&tpool->jobq.list);
 		PR_REMOVE_AND_INIT_LINK(head);
 		jobp = JOB_LINKS_PTR(head);
 		tpool->jobq.cnt--;
-
-		if (!jobp->joinable) {
-			delete_job(jobp);
-		} else {
-			PR_Lock(jobp->jlock);
-			jobp->status = JOB_CANCELED;
-			PR_NotifyCondVar(jobp->join_cv);
-			PR_Unlock(jobp->jlock);
-		}
+		delete_job(jobp);
 	}
 
+	/* delete io jobs */
 	while (!PR_CLIST_IS_EMPTY(&tpool->ioq.list)) {
 		PRJob *jobp;
 
 		head = PR_LIST_HEAD(&tpool->ioq.list);
 		PR_REMOVE_AND_INIT_LINK(head);
 		tpool->ioq.cnt--;
 		jobp = JOB_LINKS_PTR(head);
-		if (!jobp->joinable) {
-			delete_job(jobp);
-		} else {
-			PR_Lock(jobp->jlock);
-			jobp->status = JOB_CANCELED;
-			PR_NotifyCondVar(jobp->join_cv);
-			PR_Unlock(jobp->jlock);
-		}
+		delete_job(jobp);
 	}
 
+	/* delete timer jobs */
 	while (!PR_CLIST_IS_EMPTY(&tpool->timerq.list)) {
 		PRJob *jobp;
 
 		head = PR_LIST_HEAD(&tpool->timerq.list);
 		PR_REMOVE_AND_INIT_LINK(head);
 		tpool->timerq.cnt--;
 		jobp = JOB_LINKS_PTR(head);
-		if (!jobp->joinable) {
-			delete_job(jobp);
-		} else {
-			PR_Lock(jobp->jlock);
-			jobp->status = JOB_CANCELED;
-			PR_NotifyCondVar(jobp->join_cv);
-			PR_Unlock(jobp->jlock);
-		}
+		delete_job(jobp);
 	}
 
 	PR_ASSERT(0 == tpool->jobq.cnt);
 	PR_ASSERT(0 == tpool->ioq.cnt);
 	PR_ASSERT(0 == tpool->timerq.cnt);
 
 	delete_threadpool(tpool);
 	return rval;
--- a/pr/src/nspr.rc
+++ b/pr/src/nspr.rc
@@ -17,16 +17,20 @@
  */
 
 #include "prinit.h"
 #include <winver.h>
 
 #define MY_LIBNAME "nspr"
 #define MY_FILEDESCRIPTION "NSPR Library"
 
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
 #ifdef _DEBUG
 #define MY_DEBUG_STR " (debug)"
 #define MY_FILEFLAGS_1 VS_FF_DEBUG
 #else
 #define MY_DEBUG_STR ""
 #define MY_FILEFLAGS_1 0x0L
 #endif
 #if PR_BETA
@@ -61,17 +65,17 @@ BEGIN
     BLOCK "StringFileInfo"
     BEGIN
         BLOCK "040904B0" // Lang=US English, CharSet=Unicode
         BEGIN
             VALUE "CompanyName", "Netscape Communications Corporation\0"
             VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
             VALUE "FileVersion", PR_VERSION "\0"
             VALUE "InternalName", MY_INTERNAL_NAME "\0"
-            VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+            VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
             VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
             VALUE "ProductName", "Netscape Portable Runtime\0"
             VALUE "ProductVersion", PR_VERSION "\0"
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x409, 1200
--- a/pr/src/prvrsion.c
+++ b/pr/src/prvrsion.c
@@ -37,17 +37,24 @@
 #define _PRODUCTION ""
 #endif
 #if defined(DEBUG)
 #define _DEBUG_STRING " (debug)"
 #else
 #define _DEBUG_STRING ""
 #endif
 
-PRVersionDescription prVersionDescription_libnspr3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libnspr, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
 {
     /* version          */  2,                  /* this is the only one supported */
     /* buildTime        */  _BUILD_TIME,        /* usecs since midnight 1/1/1970 GMT */
     /* buildTimeString  */  _BUILD_STRING,       /*    ditto, but human readable */
     /* vMajor           */  PR_VMAJOR,          /* NSPR's version number */
     /* vMinor           */  PR_VMINOR,          /*  and minor version */
     /* vPatch           */  PR_VPATCH,          /*  and patch */
     /* beta             */  PR_BETA,            /* beta build boolean */
@@ -87,13 +94,13 @@ PR_IMPLEMENT(const PRVersionDescription*
      * Add dummy references to rcsid and sccsid to prevent them
      * from being optimized away as unused variables.
      */ 
     const char *dummy;
 
     dummy = rcsid;
     dummy = sccsid;
 #endif
-    return &prVersionDescription_libnspr3;
+    return &VERSION_DESC_NAME;
 }  /* versionEntryPointType */
 
 /* prvrsion.c */
 
--- a/pr/src/pthreads/ptio.c
+++ b/pr/src/pthreads/ptio.c
@@ -138,33 +138,32 @@ static ssize_t (*pt_aix_sendfile_fptr)()
     || defined(HPUX10_30) || defined(HPUX11) || defined(LINUX) \
     || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
     || defined(BSDI) || defined(VMS) || defined(NTO)
 #define _PRSelectFdSetArg_t fd_set *
 #else
 #error "Cannot determine architecture"
 #endif
 
-static PRFileDesc *pt_SetMethods(PRIntn osfd, PRDescType type);
+static PRFileDesc *pt_SetMethods(
+    PRIntn osfd, PRDescType type, PRBool isAcceptedSocket);
 
 static PRLock *_pr_flock_lock;  /* For PR_LockFile() etc. */
 static PRLock *_pr_rename_lock;  /* For PR_Rename() */
 
 /**************************************************************************/
 
 /* These two functions are only used in assertions. */
 #if defined(DEBUG)
 
-static PRBool IsValidNetAddr(const PRNetAddr *addr)
+PRBool IsValidNetAddr(const PRNetAddr *addr)
 {
     if ((addr != NULL)
             && (addr->raw.family != AF_UNIX)
-#ifdef _PR_INET6
-            && (addr->raw.family != AF_INET6)
-#endif
+            && (addr->raw.family != PR_AF_INET6)
             && (addr->raw.family != AF_INET)) {
         return PR_FALSE;
     }
     return PR_TRUE;
 }
 
 static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
 {
@@ -185,17 +184,17 @@ static PRBool IsValidNetAddrLen(const PR
 /*****************************************************************************/
 /************************* I/O Continuation machinery ************************/
 /*****************************************************************************/
 
 /*
  * The polling interval defines the maximum amount of time that a thread
  * might hang up before an interrupt is noticed.
  */
-#define PT_DEFAULT_POLL_MSEC 100
+#define PT_DEFAULT_POLL_MSEC 5000
 
 /*
  * pt_SockLen is the type for the length of a socket address
  * structure, used in the address length argument to bind,
  * connect, accept, getsockname, getpeername, etc.  Posix.1g
  * defines this type as socklen_t.  It is size_t or int on
  * most current systems.
  */
@@ -212,27 +211,21 @@ typedef PRIntn pt_SockLen;
 #endif
 
 typedef struct pt_Continuation pt_Continuation;
 typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revents);
 
 typedef enum pr_ContuationStatus
 {
     pt_continuation_pending,
-    pt_continuation_recycle,
-    pt_continuation_abort,
     pt_continuation_done
 } pr_ContuationStatus;
 
 struct pt_Continuation
 {
-    /* These objects are linked in ascending timeout order */
-    pt_Continuation *next, *prev;           /* self linked list of these things */
-
-    PRFileDesc *fd;
     /* The building of the continuation operation */
     ContinuationFn function;                /* what function to continue */
     union { PRIntn osfd; } arg1;            /* #1 - the op's fd */
     union { void* buffer; } arg2;           /* #2 - primary transfer buffer */
     union {
         PRSize amount;                      /* #3 - size of 'buffer', or */
         pt_SockLen *addr_len;                  /*    - length of address */
 #ifdef HPUX11
@@ -253,50 +246,30 @@ struct pt_Continuation
     /*
      * For sendfile()
      */
     int filedesc;                           /* descriptor of file to send */
     int nbytes_to_send;                     /* size of header and file */
 #endif  /* HPUX11 */
     
     PRIntervalTime timeout;                 /* client (relative) timeout */
-    PRIntervalTime absolute;                /* internal (absolute) timeout */
 
     PRInt16 event;                           /* flags for poll()'s events */
 
     /*
     ** The representation and notification of the results of the operation.
     ** These function can either return an int return code or a pointer to
     ** some object.
     */
     union { PRSize code; void *object; } result;
 
     PRIntn syserrno;                        /* in case it failed, why (errno) */
     pr_ContuationStatus status;             /* the status of the operation */
-    PRCondVar *complete;                    /* to notify the initiating thread */
-	PRIntn io_tq_index;                     /* io-queue index */
 };
 
-static struct pt_TimedQueue
-{
-    PRLock *ml;                             /* a little protection */
-    PRThread *thread;                       /* internal thread's identification */
-    PRUintn op_count;                       /* number of operations in the list */
-    pt_Continuation *head, *tail;           /* head/tail of list of operations */
-
-    pt_Continuation *op;                    /* timed operation furthest in future */
-    struct pollfd *pollingList;             /* list built for polling */
-    PRIntn pollingSlotsAllocated;           /* # entries available in list */
-    pt_Continuation **pollingOps;           /* list paralleling polling list */
-} *pt_tqp;  /* an array */
-
-static PRIntn _pt_num_cpus;
-PRIntn _pt_tq_count;                        /* size of the pt_tqp array */
-static PRInt32 _pt_tq_index;                /* atomically incremented */
-
 #if defined(DEBUG)
 
 PTDebug pt_debug;  /* this is shared between several modules */
 
 PR_IMPLEMENT(void) PT_GetStats(PTDebug* here) { *here = pt_debug; }
 
 PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
 {
@@ -311,682 +284,168 @@ PR_IMPLEMENT(void) PT_FPrintStats(PRFile
     LL_SUB(elapsed, PR_Now(), stats.timeStarted);
     LL_I2L(aMil, 1000000);
     LL_DIV(elapsed, elapsed, aMil);
     
     if (NULL != msg) PR_fprintf(debug_out, "%s", msg);
     PR_fprintf(
         debug_out, "\tstarted: %s[%lld]\n", buffer, elapsed);
     PR_fprintf(
-        debug_out, "\tmissed predictions: %u\n", stats.predictionsFoiled);
-    PR_fprintf(
-        debug_out, "\tpollingList max: %u\n", stats.pollingListMax);
-    PR_fprintf(
-        debug_out, "\tcontinuations served: %u\n", stats.continuationsServed);
-    PR_fprintf(
-        debug_out, "\trecycles needed: %u\n", stats.recyclesNeeded);
-    PR_fprintf(
-        debug_out, "\tquiescent IO: %u\n", stats.quiescentIO);
-    PR_fprintf(
         debug_out, "\tlocks [created: %u, destroyed: %u]\n",
         stats.locks_created, stats.locks_destroyed);
     PR_fprintf(
         debug_out, "\tlocks [acquired: %u, released: %u]\n",
         stats.locks_acquired, stats.locks_released);
     PR_fprintf(
         debug_out, "\tcvars [created: %u, destroyed: %u]\n",
         stats.cvars_created, stats.cvars_destroyed);
     PR_fprintf(
         debug_out, "\tcvars [notified: %u, delayed_delete: %u]\n",
         stats.cvars_notified, stats.delayed_cv_deletes);
 }  /* PT_FPrintStats */
 
 #endif  /* DEBUG */
 
-/*
- * The following two functions, pt_InsertTimedInternal and
- * pt_FinishTimedInternal, are always called with the tqp->ml
- * lock held.  The "internal" in the functions' names come from
- * the Mesa programming language.  Internal functions are always
- * called from inside a monitor.
- */
-
-static void pt_InsertTimedInternal(pt_Continuation *op)
+static void pt_poll_now(pt_Continuation *op)
 {
-    pt_Continuation *t_op = NULL;
-    PRIntervalTime now = PR_IntervalNow();
-	struct pt_TimedQueue *tqp = &pt_tqp[op->io_tq_index];
-
-#if defined(DEBUG)
-    {
-        PRIntn count;
-        pt_Continuation *tmp;
-        PRThread *self = PR_GetCurrentThread();
-
-        PR_ASSERT(tqp == &pt_tqp[self->io_tq_index]);
-        PR_ASSERT((tqp->head == NULL) == (tqp->tail == NULL));
-        PR_ASSERT((tqp->head == NULL) == (tqp->op_count == 0));
-        for (tmp = tqp->head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
-        PR_ASSERT(count == tqp->op_count);
-        for (tmp = tqp->tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
-        PR_ASSERT(count == tqp->op_count);
-        for (tmp = tqp->head; tmp != NULL; tmp = tmp->next)
-            PR_ASSERT(tmp->io_tq_index == op->io_tq_index);
-    }
-#endif /* defined(DEBUG) */
-
-    /*
-     * If this element operation isn't timed, it gets queued at the
-     * end of the list (just after tqp->tail) and we're
-     * finishd early.
-     */
-    if (PR_INTERVAL_NO_TIMEOUT == op->timeout)
-    {
-        t_op = tqp->tail;  /* put it at the end */
-        goto done;
-    }
-
-    /*
-     * The portion of this routine deals with timed ops.
-     */
-    op->absolute = now + op->timeout;  /* absolute ticks */
-    if (NULL == tqp->op) tqp->op = op;
-    else
-    {
-        /*
-         * To find where in the list to put the new operation, based
-         * on the absolute time the operation in question will expire.
-         *
-         * The new operation ('op') will expire at now() + op->timeout.
-         *
-         * This should be easy!
-         */
-
-        for (t_op = tqp->op; NULL != t_op; t_op = t_op->prev)
-        {
-            /*
-             * If 'op' expires later than t_op, then insert 'op' just
-             * ahead of t_op. Otherwise, compute when operation[n-1]
-             * expires and try again.
-             *
-             * The actual difference between the expiriation of 'op'
-             * and the current operation what becomes the new operaton's
-             * timeout interval. That interval is also subtracted from
-             * the interval of the operation immediately following where
-             * we stick 'op' (unless the next one isn't timed). The new
-             * timeout assigned to 'op' takes into account the values of
-             * now() and when the previous intervals were computed.
-             */
-            if ((PRInt32)(op->absolute - t_op->absolute) >= 0)
-            {
-                if (t_op == tqp->op) tqp->op = op;
-                break;
-            }
-        }
-    }
-
-done:
-
-    /*
-     * Insert 'op' into the queue just after t_op or if t_op is null,
-     * at the head of the list.
-     *
-     * We need to set up the 'next' and 'prev' pointers of 'op'
-     * correctly before inserting 'op' into the queue.  Also, we insert
-     * 'op' by updating tqp->head or op->prev->next first, and then
-     * updating op->next->prev.  We want to make sure that the 'next'
-     * pointers are linked up correctly at all times so that we can
-     * traverse the queue by starting with tqp->head and following
-     * the 'next' pointers, without having to acquire the tqp->ml lock.
-     * (we do that in pt_ContinuationThreadInternal).  We traverse the 'prev'
-     * pointers only in this function, which is called with the lock held.
-     *
-     * Similar care is taken in pt_FinishTimedInternal where we remove
-     * an op from the queue.
-     */
-    if (NULL == t_op)
-    {
-        op->prev = NULL;
-        op->next = tqp->head;
-        tqp->head = op;
-        if (NULL == tqp->tail) tqp->tail = op;
-        else op->next->prev = op;
-    }
-    else
-    {
-        op->prev = t_op;
-        op->next = t_op->next;
-        if (NULL != op->prev)
-            op->prev->next = op;
-        if (NULL != op->next)
-            op->next->prev = op;
-        if (t_op == tqp->tail)
-            tqp->tail = op;
-    }
-
-    tqp->op_count += 1;
-
-#if defined(DEBUG)
-    {
-        PRIntn count;
-        pt_Continuation *tmp;
-        PR_ASSERT(tqp->head != NULL);
-        PR_ASSERT(tqp->tail != NULL);
-        PR_ASSERT(tqp->op_count != 0);
-        PR_ASSERT(tqp->head->prev == NULL);
-        PR_ASSERT(tqp->tail->next == NULL);
-        if (tqp->op_count > 1)
-        {
-            PR_ASSERT(tqp->head->next != NULL);
-            PR_ASSERT(tqp->tail->prev != NULL);
-        }
-        else
-        {
-            PR_ASSERT(tqp->head->next == NULL);
-            PR_ASSERT(tqp->tail->prev == NULL);
-        }
-        for (tmp = tqp->head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
-        PR_ASSERT(count == tqp->op_count);
-        for (tmp = tqp->tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
-        PR_ASSERT(count == tqp->op_count);
-    }
-#endif /* defined(DEBUG) */
-
-}  /* pt_InsertTimedInternal */
-
-/*
- * function: pt_FinishTimedInternal
- *
- * Takes the finished operation out of the timed queue. It
- * notifies the initiating thread that the opertions is
- * complete and returns to the caller the value of the next
- * operation in the list (or NULL).
- */
-static pt_Continuation *pt_FinishTimedInternal(pt_Continuation *op)
-{
-    pt_Continuation *next;
-	struct pt_TimedQueue *tqp = &pt_tqp[op->io_tq_index];
-
-#if defined(DEBUG)
-    {
-        PRIntn count;
-        pt_Continuation *tmp;
-        PR_ASSERT(tqp->head != NULL);
-        PR_ASSERT(tqp->tail != NULL);
-        PR_ASSERT(tqp->op_count != 0);
-        PR_ASSERT(tqp->head->prev == NULL);
-        PR_ASSERT(tqp->tail->next == NULL);
-        if (tqp->op_count > 1)
-        {
-            PR_ASSERT(tqp->head->next != NULL);
-            PR_ASSERT(tqp->tail->prev != NULL);
-        }
-        else
-        {
-            PR_ASSERT(tqp->head->next == NULL);
-            PR_ASSERT(tqp->tail->prev == NULL);
-        }
-        for (tmp = tqp->head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
-        PR_ASSERT(count == tqp->op_count);
-        for (tmp = tqp->tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
-        PR_ASSERT(count == tqp->op_count);
-    }
-#endif /* defined(DEBUG) */
-
-    /* remove this one from the list */
-    if (NULL == op->prev) tqp->head = op->next;
-    else op->prev->next = op->next;
-    if (NULL == op->next) tqp->tail = op->prev;
-    else op->next->prev = op->prev;
-
-    /* did we happen to hit the timed op? */
-    if (op == tqp->op) tqp->op = op->prev;
-
-    next = op->next;
-    op->next = op->prev = NULL;
-    op->status = pt_continuation_done;
-
-    tqp->op_count -= 1;
-
-#if defined(DEBUG)
-    pt_debug.continuationsServed += 1;
-#endif
-    PR_NotifyCondVar(op->complete);
-
-#if defined(DEBUG)
-    {
-        PRIntn count;
-        pt_Continuation *tmp;
-        PR_ASSERT((tqp->head == NULL) == (tqp->tail == NULL));
-        PR_ASSERT((tqp->head == NULL) == (tqp->op_count == 0));
-        for (tmp = tqp->head, count = 0; tmp != NULL; tmp = tmp->next) count += 1;
-        PR_ASSERT(count == tqp->op_count);
-        for (tmp = tqp->tail, count = 0; tmp != NULL; tmp = tmp->prev) count += 1;
-        PR_ASSERT(count == tqp->op_count);
-    }
-#endif /* defined(DEBUG) */
-
-    return next;
-}  /* pt_FinishTimedInternal */
-
-static void pt_ContinuationThreadInternal(pt_Continuation *my_op)
-{
-    /* initialization */
-    PRInt32 msecs, mx_poll_ticks;
-    PRThreadPriority priority;              /* used to save caller's prio */
-    PRIntn pollingListUsed;                 /* # entries used in the list */
-    PRIntn pollingListNeeded;               /* # entries needed this time */
-    PRIntn io_tq_index = my_op->io_tq_index;
-    struct pt_TimedQueue *tqp = &pt_tqp[my_op->io_tq_index];
-    struct pollfd *pollingList = tqp->pollingList;
-    PRIntn pollingSlotsAllocated = tqp->pollingSlotsAllocated;
-    pt_Continuation **pollingOps = tqp->pollingOps;
+    PRInt32 msecs;
+	PRIntervalTime epoch, now, elapsed, remaining;
+    PRThread *self = PR_GetCurrentThread();
     
-    PR_Unlock(tqp->ml);  /* don't need that silly lock for a bit */
-
-    priority = PR_GetThreadPriority(tqp->thread);
-    PR_SetThreadPriority(tqp->thread, PR_PRIORITY_HIGH);
-
-    mx_poll_ticks = (PRInt32)PR_MillisecondsToInterval(PT_DEFAULT_POLL_MSEC);
-
-    /* do some real work */
-    while (PR_TRUE)
-    {
-        PRIntn rv;
-        PRInt32 timeout;
-        PRIntn pollIndex;
-        PRIntervalTime now;
-        pt_Continuation *op, *next_op;
-
-        PR_ASSERT(NULL != tqp->head);
-
-        pollingListNeeded = tqp->op_count;
-
-    /*
-     * We are not holding the tqp->ml lock now, so more items may
-     * get added to pt_tq during this window of time.  We hope
-     * that 10 more spaces in the polling list should be enough.
-     *
-     * The space allocated is for both a vector that parallels the
-     * polling list, providing pointers directly into the operation's
-     * table and the polling list itself. There is a guard element
-     * between the two structures.
-     */
-        pollingListNeeded += 10;
-        if (pollingListNeeded > pollingSlotsAllocated)
-        {
-            if (NULL != pollingOps) PR_Free(pollingOps);
-            pollingOps = (pt_Continuation**)PR_Malloc(
-                sizeof(pt_Continuation**) + pollingListNeeded * 
-                    (sizeof(struct pollfd) + sizeof(pt_Continuation*)));
-            PR_ASSERT(NULL != pollingOps);
-			tqp->pollingOps = pollingOps;
-            pollingSlotsAllocated = pollingListNeeded;
-			tqp->pollingSlotsAllocated = pollingSlotsAllocated;
-            pollingOps[pollingSlotsAllocated] = (pt_Continuation*)-1;
-            pollingList = (struct pollfd*)(&pollingOps[pollingSlotsAllocated + 1]);
-			tqp->pollingList = pollingList;
-            
-        }
-
-#if defined(DEBUG)
-        if (pollingListNeeded > pt_debug.pollingListMax)
-            pt_debug.pollingListMax = pollingListNeeded;
-#endif
-
-        /*
-        ** This is interrupt processing. If this thread was interrupted,
-        ** the thread state will have the PT_THREAD_ABORTED bit set. This
-        ** overrides good completions as well as timeouts.
-        **
-        ** BTW, it does no good to hold the lock here. This lock doesn't
-        ** protect the thread structure in any way. Testing the bit and
-        ** (perhaps) resetting it are safe 'cause it's the only modifiable
-        ** bit in that word.
-        */
-        if (_PT_THREAD_INTERRUPTED(tqp->thread))
-        {
-            my_op->status = pt_continuation_abort;
-            tqp->thread->state &= ~PT_THREAD_ABORTED;
-        }
-
-
-        /*
-         * Build up a polling list.
-         * This list is sorted on time. Operations that have been
-         * interrupted are completed and not included in the list.
-         * There is an assertion that the operation is in progress.
-         */
-        pollingListUsed = 0;
-        PR_Lock(tqp->ml);
-
-        for (op = tqp->head; NULL != op;)
-        {
-            if (pt_continuation_abort == op->status)
-            {
-                op->result.code = -1;
-                op->syserrno = EINTR;
-                next_op = pt_FinishTimedInternal(op);
-                if (op == my_op) goto recycle;
-                else op = next_op;
-                PR_ASSERT(NULL != tqp->head);
-            }
-            else
-            {
-                op->status = pt_continuation_pending;
-                if (pollingListUsed >= pollingSlotsAllocated)
-                {
-#if defined(DEBUG)
-                    pt_debug.predictionsFoiled += 1;
-#endif
-                    break;
-                }
-                PR_ASSERT((pt_Continuation*)-1 == pollingOps[pollingSlotsAllocated]);
-                /*
-                 * eventMask bitmasks are declared as PRIntn so that
-                 * each bitm